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

Java 无法通过Netty从服务器向客户端发送消息,java,netty,nio,Java,Netty,Nio,我刚刚开始学习Netty,如果这听起来真的很愚蠢,请耐心听我说 我试图完成的是在成功连接到客户机后,要求服务器向客户机发送ping消息。为此,我已重写了ChannelInboundHandlerAdapter类的channelActive方法。当客户机连接到服务器时,我可以看到正在打印“客户机已连接”,但不知何故,服务器没有向客户机发送消息。我想我在这里做错了什么。谁能帮帮我吗 以下是服务器中的代码片段- public class ChatServerHandler extends Channe

我刚刚开始学习
Netty
,如果这听起来真的很愚蠢,请耐心听我说

我试图完成的是在成功连接到客户机后,要求服务器向客户机发送ping消息。为此,我已重写了
ChannelInboundHandlerAdapter
类的
channelActive
方法。当客户机连接到服务器时,我可以看到正在打印“客户机已连接”,但不知何故,服务器没有向客户机发送消息。我想我在这里做错了什么。谁能帮帮我吗

以下是服务器中的代码片段-

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


谢谢

您需要发送一个ByteBuf来发送数据,通常在管道开始处附近的管道中会有一个编码器,负责将您的消息转换为ByteBuf发送到网络上

看看netty用户指南中的“编写时间服务器”部分

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

String msg = "ping";
final ByteBuf byteBufMsg = ctx.alloc().buffer(msg.length());
byteBufMsg.writeBytes(msg.getBytes());
ctx.writeAndFlush(byteBufMsg);
正如Norman在评论中提到的,您还可以向管道中添加一个。这是特别好的,因为它也有一个在客户端对它的赞美。在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更新为being; 字符串msg=“ping\n”; 因为它需要行结束,所以将正确地读出消息


从子类列表中可以看到其他可用的编码器,以及可用的解码器。

或者,您也可以向ChannelPipeline添加一个StringEncoder,它将为您处理String->ByteBuf中的编码。感谢@NormanMaurer!您知道《用户指南》中是否有概述一些可用编码器的内容?看了一下,除了使用,没有看到任何跳出的东西。有关其用法的更多信息,请访问。从子类中可以看到其他编码器,感谢@NormanMaurer的输入,感谢Doswell的更新答案,非常有用。
// 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());