2012-02-15 15 views
5

私はおもちゃのNettyサーバーを持っていて、チャンネルに何も起こっていないときにハートビートメッセージをクライアントに送信しようとしています。私は、サーバーにtelnettingし、メッセージを書いて何も送信しないでこれをテストしていますが、聞こえません!NettyのトラブルIdleStateHandler - 間違った方法でテストしていますか?

コンソール:固定

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

答えて

9

ChannelPipelineにHeartbeatHandlerを追加できませんでした。それを動作させるには、IdleStateHandler HeartbeatHandlerをChannelPipelineに追加する必要があります。

+1

ああ、私は両方の必要があることをドキュメントからはっきりしていませんでした。もう一度 – nflacco

+0

HeartbeatHandlerはもはや3.5.9では必要ないのでしょうか? –

+0

それでもどちらも必要です –

1

ノーマンの回答は本当に役に立ちますが、別のことを指摘したいと思います:idleStateHandlerとheartbeatHandlerはチャネル固有である必要があります。そのため、PipeLineFactoryでは、これら2つのハンドラをプライベートメンバーとして構築しないでください。 getPipeline()メソッドで新しいものを作成する必要があります。構築されたチャネルを保存するためのチャネルマップもあります。解放する必要がある場合は、タイマーを停止してリソースを解放することをお勧めします。

+0

IdleStateHandlerは共有可能なので、すべてのパイプラインに新しいインスタンスを作成する必要はないと思います。 – WorM

関連する問題