2012-01-23 4 views
4

Как я могу закрыть канал/соединение WebSocket с серверной стороны правильно? Если я использую ctx.getChannel().close(), то onerror в Brwoser (Firefox 9) отбрасывается:Netty: Правильно закрыты WebSockets

Подключение к WS: // локальный: 8080/WebSocket была прервана, когда страница была загрузка

Я также попытался отправить CloseWebSocketFrame в channelClosed -метода в WebSocketServerHandler:

public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) 
     throws Exception { 
    CloseWebSocketFrame close = new CloseWebSocketFrame(); 
    ctx.getChannel().write(close); 
} 

Это бросает ClosedChannelException (возможно, связанные to this?).

ответ

4

Вы должны сделать это:

ch.write(new CloseWebSocketFrame()); 

тогда сервер закрывает соединение. Если соединение не закрывается достаточно быстро, вы можете позвонить ch.close().

+0

После того, как соединение WebSocket установлено, моя труба выглядит так: '[wsdecoder, wsencoder, webSocketHandler, myDecoder, myEncoder, app]'. Таким образом, WebSocketHandler пересылает данные в декодер, пока не достигнет приложения. Проблема в том, что 'app' ничего не знает о том, как он используется. Таким образом, он не знает, что в трубе вообще есть WebSocketHandler. Подобным образом, 'app' может использоваться и в других каналах с не-WebSocket-соединениями. Даже если я напишу «CloseWebSocketFrame» в приложении к «каналу», он будет закодирован до тех пор, пока он не достигнет «WebSocketServerHandler» – Dennis

+0

. Я просто что-то протестировал: правильно ли это, что 'ch.write (...)' на любом слое трубы проходит через всю трубу (от последнего до первого обработчика)? Я ожидал, что он просто вернется из слоя, где мы делаем 'ch.write (...)' – Dennis

+2

Из-за последнего поведения я представил класс ChannelClosing. Я пишу экземпляр этого на канале: 'ch.write (new ChannelClosing());'. Если я нахожу это в своем декодере (который преобразует данные моего приложения в WebSockets), я перехожу к 'CloseWebSocketFrame'. Оно работает. – Dennis

0

Какая версия вы используете?

Вы пробовали TODO это:

ctx.getChannel().write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); 

?

+0

Nope. Тем не менее 'ClosedChannelException'. Конструктор 'CloseWebSocketFrame' содержит' ChannelBuffers.EMPTY_BUFFER'. Думаю, мне нужно использовать 'CloseWebSocketFrame'. – Dennis

+0

RFC 6455 (http://tools.ietf.org/html/rfc6455#section-7.4.1) определяет: * 1001 указывает, что конечная точка «уходит», например, сбой сервера или навигатор с навигацией от страницы. * Это то, что я хочу использовать. – Dennis

+0

Версия: Я использую свою ветку (https://github.com/boldt/netty). Поскольку Netty является модульным, я больше не могу его компилировать. – Dennis

1

Как насчет

ctx.getChannel().write(new CloseWebSocketFrame()).addListener(ChannelFutureListener.CLOSE); 

Это должно послать CloseWebSocketFrame, а затем закрыть канал после этого.

Смежные вопросы