2015-07-25 4 views
2

Я никогда раньше не работал с Netty, и я создал Netty-сервер. Когда я что-то посылаю, channelRead0 никогда не запускается; только channelRead. Почему это и как я могу вызвать его? Я использую netty версии 4.0.12. Благодаря!Netty channelRead0 не работает

Сервер:

void run() { 

    EventLoopGroup bossGroup = new NioEventLoopGroup(); 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 

    try { 
     ServerBootstrap b = new ServerBootstrap(); 
     b.group(bossGroup, workerGroup) 
       .channel(NioServerSocketChannel.class) 
       .option(ChannelOption.SO_BACKLOG, 100) 
       .childHandler(new UTFServerInitializer()); 

     ChannelFuture f = b.bind(this.port).sync(); 
     f.channel().closeFuture().sync(); 

    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } finally { 
     workerGroup.shutdownGracefully(); 
     bossGroup.shutdownGracefully(); 
    } 

} 

Initializer Handler:

static class UTFServerInitializer extends ChannelInitializer<SocketChannel> { 

    @Override 
    protected void initChannel(SocketChannel channel) throws Exception { 

     ChannelPipeline pipeline = channel.pipeline(); 

     pipeline.addLast("UTFHandler", new UTFServerHandler()); 
    } 

} 

обработчика вызовов:

static class UTFServerHandler extends SimpleChannelInboundHandler<String> { 

    @Override 
    public void channelRead(ChannelHandlerContext arg0, Object arg1) 
      throws Exception { 

     ByteBuf in = (ByteBuf) arg1; 

     try { 
      while (in.isReadable()) { 
       System.out.print((char) in.readByte()); 
       System.out.flush(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
     } 
    } 

    @Override 
    protected void channelRead0(ChannelHandlerContext arg0, String arg1) 
      throws Exception { 
     // TODO Auto-generated method stub 

     // not fired 
     System.out.println("channelRead0"); 

    } 

    @Override 
    public void channelReadComplete(ChannelHandlerContext ctx) 
      throws Exception { 
     super.channelReadComplete(ctx); 
     System.out.println("channelReadComplete"); 

    } 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 
      throws Exception { 
     cause.printStackTrace(); 
     ctx.close(); 
    } 

} 

ответ

3

Просто поместите все ваши бизнес-логику внутри метода channelRead0 и удалить метод channelRead , В этом случае channelRead0 будет вызываться по умолчанию.

3

Вы переопределяете метод channelRead. В SimpleChannelInboundHandler существует метод шаблона, который вызывает вашу реализацию channelRead0.

@Override 
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 
    boolean release = true; 
    try { 
     if (acceptInboundMessage(msg)) { 
      @SuppressWarnings("unchecked") 
      I imsg = (I) msg; 
      channelRead0(ctx, imsg); 
     } else { 
      release = false; 
      ctx.fireChannelRead(msg); 
     } 
    } finally { 
     if (autoRelease && release) { 
      ReferenceCountUtil.release(msg); 
     } 
    } 
} 

SimpleChannelInboundHandler перехватывает определенный тип сообщения, посвященный вашим TYPENAME, например SimpleChannelInboundHandler перехватывает Integer. И вам нужно добавить StringDecoder для конвейера перед этим обработчиком для преобразования ByteBuf в String.

Смежные вопросы