无法通过Netty从服务器向客户端发送消息

时间:2014-07-24 19:40:53

标签: java netty nio

我刚开始使用Netty,所以如果听起来真的很蠢,请耐心等待。

我想要完成的是要求服务器在成功连接到客户端后向客户端发送ping消息。为此,我已经覆盖了channelActive类的ChannelInboundHandlerAdapter方法。当客户端连接到服务器时,我可以看到"客户端连接到#34;正在打印,但不知何故服务器不会将消息发送给客户端。我想我在这里做了一些非常错误的事情。有人可以帮帮我吗?

这是服务器中的代码段 -

public class ChatServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(final ChannelHandlerContext ctx) {
        System.out.println("client connected");
        String msg = "ping";
        final ChannelFuture f = ctx.writeAndFlush(msg);
        f.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) {
                if(future.isSuccess()) {
                    System.out.println("Wrote message on active");
                }
            }
        });
    }

客户代码 -

public class ChatClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("Msg: " + (String)msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.out.println("Exception...closing channel");
        ctx.close();
    }
}

问题是我在channelRead()上看不到客户端打印的消息,所以我假设服务器没有将消息发送给客户端。

如果您还需要代码的任何其他部分,请告诉我。我使用的是Netty 4.0.21。

谢谢!

1 个答案:

答案 0 :(得分:2)

您需要发送一个ByteBuf来发送数据。通常在管道起点附近的管道中将是一个编码器,负责接收您的消息并将其转换为ByteBuf以发送到网络。

查看netty用户指南的“编写时间服务器”部分; http://netty.io/wiki/user-guide-for-4.x.html

这里他们将时间值包装到ByteBuf中。 对于你的例子,你想尝试;

String msg = "ping";
final ByteBuf byteBufMsg = ctx.alloc().buffer(msg.length());
byteBufMsg.writeBytes(msg.getBytes());
ctx.writeAndFlush(byteBufMsg);

正如Norman在评论中所提到的,您还可以向管道添加StringEncoder。这是特别好的,因为它还有一个StringDecoder,它在客户端称赞它。在ChatServerHandler之前添加这些内容将允许您按照示例中的方式保留您的类。

您的管道设置看起来像(来自StringEncoder示例);

// Encoder
pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast("chatServer", new ChatServerHandler());

在您的客户端管道上;

// Decoders
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(80)); //This terminates strings on line endings, ie \n
pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("chatClient", new ChatClientHandler());

将msg更新为;     String msg =“ping \ n”; 因为它需要行结束,所以LineBasedFrameDecoder将正确读出消息。

其他可用的编码器可以从MessageToMessageEncoder子类列表中查看,也可以从MessageToMessageDecoder查看可用的解码器。