Netty IdleStateHandler的问题 – 我是以错误的方式测试它的吗?

我有一个玩具Netty服务器,我试图在他们的频道上没有发生任何事情时向客户发送心跳消息。 我通过telnet到服务器,写一条消息,然后不发送任何东西来测试这个,但我没有听到任何声音!

安慰:

>>telnet localhost 6969 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. >>foo Did you say 'foo'? 

MyPipelineFactory.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; } } 

HeartbeatHandler.java

 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才能使其正常工作。

Norman的回答非常有用,但是我想指出另一件事:idleStateHandler和heartbeatHandler应该是特定于通道的,所以在PipeLineFactory中,你不应该将这两个处理程序构造为私有成员,而是需要创建getPipeline()方法中的新的。 您还有一个通道映射来保存构建的通道,如果您需要释放它们,您最好还停止计时器以释放资源。