2013-01-09 5 views
2

우리는 대규모의 작은 요청과 HTTP 서비스를 가지고 있으며 이들 대부분은 한 번만 (약 70 %) 그래서Netty에서 모든 channelClosed 이벤트를 어떻게 잡을 수 있습니까?

요청이 올 때 우리는 채널 개방을 유지하는 경우 요청, 곧 체류 채널의 많이있을 것입니다 아무것도하지 않는 동안 메모리에.

현재 우리는 IdleStateHandler와 IdleStateAwareChannelHandler, 을 등록하여 5 초 동안 아무런 활동도없는 채널을 닫을 수 있습니다.

이것은 작동하는 것으로 보이며 열린 채널의 크기는 안정적입니다.

는하지만 우리는 또 다른 문제가 각 오픈 채널

, 우리는 정의와 연관된 ServerConnection 개체를 만들었을 는 현재 채널에 관한 유용한 정보를 저장합니다. 우리는 그 ServerConnection을 connectionMap이라는 글로벌 맵에두고 키는 채널로 유지합니다.

messageReceived가 호출 될 때마다 채널이 이미 connectionMap에 있는지 확인하고 그렇지 않은 경우 새 ServerConnection이 만들어집니다.

channelClosed/exceptionCaught 이벤트가 감지 될 때마다 connectionMap.remove를 호출하여 제거합니다.

그리고 IdleStateHandler가 호출 될 때지도에서 수동으로 제거합니다.

그러나 일부 ServerConnections는 제거되지 않고 해당 채널의 상태가 실제로 닫혀 있습니다.

뭔가 빠졌습니까? 채널이 폐쇄 된 다른 장소가 있긴하지만 이벤트를 포착하는 것을 잊어 버렸습니까?

+0

나는 당신과 비슷한 솔루션을 구현하려고합니다. 자신의 디코더를 구현 했습니까? 클라이언트가 텔넷을 닫으면 내 서버는 먼저 messageReceived를 얻은 다음 channelClosed를 얻지 만 예상 한 것은 채널 만 닫힌 것입니다. 그래서 연결 해제 또한 messageReceived 이벤트를 트리거 이해합니다. 그러나 클라이언트가 연결을 alredy 닫혀 있기 때문에 messageReceived 이벤트의 메시지는 의미가 없습니다. 그것을 해결하기 위해 내가 디코더를 구현할 수 있다면 tought 채널을 처리 할 수있는 것보다 messageReceived를 제대로 처리 할 수 ​​있습니까? 당신이 그것에 대해 어떻게 생각하십니까? –

답변

4

ChannelFutureListener 인터페이스를 사용하고 채널의 가까운 미래에 등록하면 채널이 닫힐 때 알림을받을 수 있습니다. 당신이 당신의 채널에 대해 다음

class MyClass implements ChannelFutureListener 
{ 
    // Whatever stuff this class also does 
    // ... 

    public void operationComplete(ChannelFuture future) throws Exception 
    { 
     System.out.println("This channel closed! " + 
          future.getChannel().getId().toString()); 
    } 

} 

...
channel.getCloseFuture().addListener(instanceOfMyClass); 

채널이 종료

, 당신의 ChannelFutureListener 통지됩니다.

참고로 Netty 3.x입니다. Netty 4.x는 조정할 필요가있는 몇 가지 메소드 이름을 변경했습니다 (getter로부터 get 접두어가 삭제되었습니다).

+0

이것은 모든 채널 닫기에 대해 ClosedFuture()가 호출되도록 보장됩니까? –

관련 문제