2017-06-14 17 views

Odpowiedz

2

Oto co widzę jako głównych obszarach contrastable:

Kodowanie stylu

Weźmy netty na discard server example który jest prawdopodobnie najprostszy przykład podano, że jest to pierwszy w dokumentacji.

Dla akka-http ta jest stosunkowo prosta:

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) 
} 

Dla Netty jest to o wiele bardziej gadatliwy:

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(); 
    } 
} 

Dyrektywy

Jednym z Akka HTTP największy mocnych, w moim opinia, to Directives, które zapewniają DSL dla skomplikowanej logiki obsługi żądań. Załóżmy na przykład, że chcemy odpowiedzieć jednym komunikatem dla żądań GET i PUT oraz kolejną wiadomością dla wszystkich innych metod żądań. Jest to bardzo łatwe przy użyciu dyrektyw:

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

, jeśli chcesz uzyskać element zamówienia i ilości od ścieżki żądanie:

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

Funkcjonalność ta nie istnieje w ramach Netty.

Streaming

jeden ostatni element, chciałbym zwrócić uwagę jest to około streamingu. akka-http jest oparty na akka-stream. Dlatego też, akka-http dobrze radzi sobie ze strumieniowaniem istot żądań. Weźmy przykład Looking Into the Received Data Netty jest dla Akka to wygląda

//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 muszą obsługiwać ten sam problem z buforami bajtowych i podczas pętli:

@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) 
    } 
}