2017-06-14 295 views

回答

2

這裏是我所看到的主要contrastable方面:

編碼風格

讓我們網狀的discard server example這大概是最簡單的例子給出它的文檔中的第一個。

對於akka-http這是比較簡單的:

object WebServer { 
    def main(args: Array[String]) { 

    implicit val system = ActorSystem("my-system") 
    implicit val materializer = ActorMaterializer() 

    val route = 
     extractRequestEntity { entity => 
     onComplete(entity.discardBytes(materializer)) { _ => 
      case _ => complete(StatusCodes.Ok) 
     } 
     } 

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) 
} 

對於網狀這是更爲詳細:

public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1) 

    @Override 
    public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2) 
     // Discard the received data silently. 
     ((ByteBuf) msg).release(); // (3) 
    } 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4) 
     // Close the connection when an exception is raised. 
     cause.printStackTrace(); 
     ctx.close(); 
    } 
} 

public class DiscardServer { 

    private int port; 

    public DiscardServer(int port) { 
     this.port = port; 
    } 

    public void run() throws Exception { 
     EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) 
     EventLoopGroup workerGroup = new NioEventLoopGroup(); 
     try { 
      ServerBootstrap b = new ServerBootstrap(); // (2) 
      b.group(bossGroup, workerGroup) 
      .channel(NioServerSocketChannel.class) // (3) 
      .childHandler(new ChannelInitializer<SocketChannel>() { // (4) 
       @Override 
       public void initChannel(SocketChannel ch) throws Exception { 
        ch.pipeline().addLast(new DiscardServerHandler()); 
       } 
      }) 
      .option(ChannelOption.SO_BACKLOG, 128)   // (5) 
      .childOption(ChannelOption.SO_KEEPALIVE, true); // (6) 

      // Bind and start to accept incoming connections. 
      ChannelFuture f = b.bind(port).sync(); // (7) 

      // Wait until the server socket is closed. 
      // In this example, this does not happen, but you can do that to gracefully 
      // shut down your server. 
      f.channel().closeFuture().sync(); 
     } finally { 
      workerGroup.shutdownGracefully(); 
      bossGroup.shutdownGracefully(); 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     new DiscardServer(8080).run(); 
    } 
} 

指令

一個阿卡-HTTP的最大的優勢,在我意見,是Directives,它爲複雜的請求處理邏輯提供DSL。例如,假設我們想用GETPUT請求的一條消息進行響應,並針對所有其他請求方法提供另一條消息。這用指令是很容易的:

val route = 
    (get | put) { 
    complete("You sent a GET or PUT") 
    } ~ 
    complete("Shame shame") 

,如果你想從一個請求路徑的訂單項目及數量:

val route = 
    path("order"/Segment/IntNumber) { (item, qty) => 
    complete(s"Your order: item: $item quantity: $qty") 
    } 

此功能不網狀中存在。

最後一個項目我想說明的是全能流。 akka-http基於akka-stream。因此,akka-http很好地處理了請求實體的流式性質。以網狀的Looking Into the Received Data例如,阿卡這看起來像

//a stream with a Source, intermediate processing steps, and a Sink 
val entityToConsole : (RequestEntity) => Future[Done] = 
    (_ : RequestEntity) 
    .getDataBytes() 
    .map(_.utf8String) 
    .to(Sink.foreach[String](println)) 
    .run() 

val route = 
    extractRequestEntity { entity => 
    onComplete(entityToConsole(entity)) { _ => 
     case Success(_) => complete(200, "all data written to console") 
     case Failure(_) => complete(404, "problem writing to console) 
    } 
    } 

的Netty必須用字節的緩衝區和while循環處理同樣的問題:

@Override 
public void channelRead(ChannelHandlerContext ctx, Object msg) { 
    ByteBuf in = (ByteBuf) msg; 
    try { 
     while (in.isReadable()) { // (1) 
      System.out.print((char) in.readByte()); 
      System.out.flush(); 
     } 
    } finally { 
     ReferenceCountUtil.release(msg); // (2) 
    } 
} 
相關問題