【问题标题】:Server does not realize the message sent by client in Netty 4.x在 Netty 4.x 中服务器没有实现客户端发送的消息
【发布时间】:2019-12-24 16:36:45
【问题描述】:

我尝试通过简单地实现以下示例来学习 Netty 4.x。我有一个服务器和一个客户端。在某个时间点,客户端想知道当前的日期时间,他会询问服务器“现在几点?”。当服务器意识到问题时,他会回复当前的日期时间。

我的实现如下

TimeClientInboundHandler.java

public class TimeClientInboundHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        try {
            long currentTimeMillis = (byteBuf.readUnsignedInt() - 2208988800L) * 1000L;
            System.out.println(new Date(currentTimeMillis));
            ctx.close();
        } finally {
            byteBuf.release();
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.write("What time is it?");
        ctx.flush();
    }

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

TimeServerInboundHandler.java

public class TimeServerInboundHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        try {
            byteBuf.readCharSequence(1024, StandardCharsets.UTF_8);
            System.out.println(byteBuf.toString());
        } finally {
            ((ByteBuf) msg).release();
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        final ByteBuf byteBuf = ctx.alloc().buffer(4);
        byteBuf.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));

        final ChannelFuture f = ctx.writeAndFlush(byteBuf);
        f.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                assert f == future;
                ctx.close();
            }
        });
    }

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

但是,我没有得到预期的结果。具体来说,在服务器端,问题“现在几点?”尚未在控制台上打印出来。

我做错了什么?

【问题讨论】:

    标签: java netty


    【解决方案1】:

    原因

    这个问题有两个原因。

    服务器端无法实现从客户端发送的消息,因为消息(从客户端)以错误的方式写入。而不是ctx.write("What time is it?");,我们应该实现如下ctx.write(Unpooled.coppiedBuffer("What time is it?", StandardCharsets.UTF_8);

    此外,在TimeServerInboundHandler.java 中,我们应该删除方法channelActive()。这是因为channelRead() 永远不会被触发,当然channelActive() 在频道处于活动状态时会被触发。

    解决方案

    TimeClientInboundHandler.java

    public class TimeClientInboundHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf byteBuf = (ByteBuf) msg;
            try {
                System.out.println("Client received: " + byteBuf.toString(StandardCharsets.UTF_8));
                ctx.close();
            } finally {
                byteBuf.release();
            }
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            ctx.writeAndFlush(Unpooled.copiedBuffer("What time is it?", StandardCharsets.UTF_8));
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
    

    TimeServerInboundHandler.java

    public class TimeServerInboundHandler extends ChannelInboundHandlerAdapter {
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf byteBuf = (ByteBuf) msg;
            try {
                System.out.println("Server received: " + byteBuf.toString(StandardCharsets.UTF_8));
                String answer = Utils.getCurrentTime();
                ctx.writeAndFlush(Unpooled.copiedBuffer(answer, StandardCharsets.UTF_8));
            } finally {
                ((ByteBuf) msg).release();
            }
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) {
            ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                    .addListener(ChannelFutureListener.CLOSE);
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
    

    Utils.java

    public class Utils {
        public static String getCurrentTime() {
            long currentTimeMillis = ((System.currentTimeMillis() / 1000L + 2208988800L) - 2208988800L) * 1000L;
            return new Date(currentTimeMillis).toString();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-08
      • 2017-05-23
      • 2012-12-05
      • 2015-01-05
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多