2012-02-15 7 views
5

나는 장난감 Netty 서버를 가지고 있으며 채널에 아무 것도 발생하지 않은 경우 클라이언트에게 하트 비트 메시지를 보내려고합니다. 나는 텔넷으로 서버를 테스트하고, 메시지를 작성한 다음 아무 것도 보내지 않지만, 듣고 싶지 않습니다.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"); 
     } 
    } 
} 

:

IdleStateHandler를 필요로하는 HeartbeatHandler를 잊어 버렸습니다 (이 부분은 당연하지 않습니다). 그거야.

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에서이 두 핸들러를 전용 멤버로 구성하면 안됩니다. 그러나 getPipeline() 메소드에서 새로운 것을 작성해야합니다. 생성 된 채널을 저장하기위한 채널 맵도 있습니다. 해제해야하는 경우 타이머를 중지하여 리소스를 해제하는 것이 좋습니다.

+0

IdleStateHandler는 공유 가능하므로 모든 파이프 라인에 대해 새 인스턴스를 만들어야한다고 생각하지 않습니다. – WorM