我有一个玩具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才能正常工作。