我有一个玩具 Netty 服务器,当他们的 channel 没有发生任何事情时,我试图向客户端发送心跳消息。我正在通过 telnet 连接到服务器来测试这个,写一条消息然后不发送任何东西,但我没有听到任何声音!
安慰:
>>telnet localhost 6969
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
>>foo
Did you say 'foo'?
我的管道工厂.java
public class MyPipelineFactory implements ChannelPipelineFactory {
private final Timer timer;
private static final ChannelHandler stringDecoder = new StringDecoder();
private static final ChannelHandler stringEncoder = new StringEncoder();
private final ChannelHandler idleStateHandler;
public MyPipelineFactory(Timer t) {
this.timer = t;
this.idleStateHandler = new IdleStateHandler(timer, 5, 5, 5);
}
public ChannelPipeline getPipeline() {
// create default pipeline from static method
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("idleStateHandler", this.idleStateHandler); // heartbeat
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
//pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024,0,1)); // get header from message
pipeline.addLast("stringDecoder", stringDecoder);
pipeline.addLast("stringEncoder", stringEncoder);
pipeline.addLast("ServerHandler", new ServerHandler()); // goes at the end
return pipeline;
}
}
心跳处理程序
public class HeartbeatHandler extends IdleStateAwareChannelHandler {
@Override
public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) {
if (e.getState() == IdleState.READER_IDLE) {
System.out.println("Reader idle, closing channel");
//e.getChannel().close();
e.getChannel().write("heartbeat-reader_idle");
}
else if (e.getState() == IdleState.WRITER_IDLE) {
System.out.println("Writer idle, sending heartbeat");
e.getChannel().write("heartbeat-writer_idle");
}
else if (e.getState() == IdleState.ALL_IDLE) {
System.out.println("All idle, sending heartbeat");
e.getChannel().write("heartbeat-all_idle");
}
}
}
固定的:
我忘记了 HeartbeatHandler,它需要 IdleStateHandler(这部分对我来说并不明显)。这样可行。
public class MyPipelineFactory implements ChannelPipelineFactory {
private final Timer timer;
private static final ChannelHandler stringDecoder = new StringDecoder();
private static final ChannelHandler stringEncoder = new StringEncoder();
private final ChannelHandler idleStateHandler;
private final ChannelHandler heartbeatHandler;
public MyPipelineFactory(Timer t) {
this.timer = t;
this.idleStateHandler = new IdleStateHandler(timer, 5, 5, 5);
this.heartbeatHandler = new HeartbeatHandler();
}
public ChannelPipeline getPipeline() {
// create default pipeline from static method
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("idleStateHandler", this.idleStateHandler);
pipeline.addLast("heartbeatHandler", this.heartbeatHandler); // heartbeat
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
//pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024,0,1)); // get header from message
pipeline.addLast("stringDecoder", stringDecoder);
pipeline.addLast("stringEncoder", stringEncoder);
pipeline.addLast("ServerHandler", new ServerHandler()); // goes at the end
return pipeline;
}
}
最佳答案
您错过了在 ChannelPipeline 中添加 HeartbeatHandler。您需要将 IdleStateHandler 和 HeartbeatHandler 添加到 ChannelPipeline 才能使其工作。