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

标签 java netty nio

我刚刚开始使用 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 用户指南的编写时间服务器部分; 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 更新为being; 字符串 msg = "ping\n"; 因为它需要行结尾,所以 LineBasedFrameDecoder将正确读出消息。

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

关于java - 无法通过 Netty 从服务器向客户端发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24942589/

相关文章:

java - 在 Java 中将 MySQL 数据库项存储在 ArrayList 中

java - 阅读Web服务,我有一个WSDL

Netty HttpClient - 响应超时与读取超时

java - 注册多个SelectionKey

Java Files.copy 抛出带有符号链接(symbolic link)的 FileNotFoundException

java - 尝试使用nutch进行爬网时出错-自己的本地主机名上的java.net.UnknownHostException

java - 比较相同的字符给出不同的结果

java - 在 netty 4.1 中如何在没有 channel 的情况下新建一个 promise

java - Java 的 Netty 和 GUI

java - 使用 FileSystems.newFileSystem(URI uri, Map<String, ?> env) 时出错