我刚开始使用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。
谢谢!
答案 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查看可用的解码器。