diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java index 0aa9677613..de6abb2698 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandler.java @@ -17,6 +17,7 @@ package io.netty.handler.codec.http.websocketx; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelStateHandler; import io.netty.handler.codec.http.HttpHeaders; import java.net.URI; @@ -30,12 +31,31 @@ import java.net.URI; * the {@code handleCloseFrames} is {@code false}, default is {@code true}. * * This implementation will establish the websocket connection once the connection to the remote server was complete. + * + * To know once a handshake was done you can intercept the + * {@link ChannelStateHandler#userEventTriggered(ChannelHandlerContext, Object)} and check if the event was of type + * {@link ClientHandshakeStateEvent#HANDSHAKE_ISSUED} or {@link ClientHandshakeStateEvent#HANDSHAKE_COMPLETE}. */ public class WebSocketClientProtocolHandler extends WebSocketProtocolHandler { private final WebSocketClientHandshaker handshaker; private final boolean handleCloseFrames; + /** + * Events that are fired to notify about handshake status + */ + public enum ClientHandshakeStateEvent { + /** + * The Handshake was started but the server did not response yet to the request + */ + HANDSHAKE_ISSUED, + + /** + * The Handshake was complete succesful and so the channel was upgraded to websockets + */ + HANDSHAKE_COMPLETE + } + /** * Base constructor * diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java index 0463a0e3cb..cbe1bf7878 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java @@ -15,6 +15,7 @@ */ package io.netty.handler.codec.http.websocketx; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; @@ -28,15 +29,27 @@ class WebSocketClientProtocolHandshakeHandler extends ChannelInboundMessageHandl } @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { + public void channelActive(final ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); - handshaker.handshake(ctx.channel()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); + handshaker.handshake(ctx.channel()).addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + ctx.fireExceptionCaught(future.cause()); + } else { + ctx.fireUserEventTriggered( + WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_ISSUED); + } + } + }); } @Override public void messageReceived(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { if (!handshaker.isHandshakeComplete()) { handshaker.finishHandshake(ctx.channel(), msg); + ctx.fireUserEventTriggered( + WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE); ctx.pipeline().removeAndForward(this); return; } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java index 1719b9d941..2fed4a3490 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java @@ -20,6 +20,7 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; +import io.netty.channel.ChannelStateHandler; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; @@ -40,9 +41,23 @@ import static io.netty.handler.codec.http.HttpVersion.*; * The implementation of this handler assumes that you just want to run a websocket server and not process other types * HTTP requests (like GET and POST). If you wish to support both HTTP requests and websockets in the one server, refer * to the io.netty.example.http.websocketx.server.WebSocketServer example. + * + * To know once a handshake was done you can intercept the + * {@link ChannelStateHandler#userEventTriggered(ChannelHandlerContext, Object)} and check if the event was of type + * {@link ServerHandshakeStateEvent#HANDSHAKE_COMPLETE}. */ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler { + /** + * Events that are fired to notify about handshake status + */ + public enum ServerHandshakeStateEvent { + /** + * The Handshake was complete succesful and so the channel was upgraded to websockets + */ + HANDSHAKE_COMPLETE + } + private static final AttributeKey HANDSHAKER_ATTR_KEY = new AttributeKey(WebSocketServerHandshaker.class.getName()); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java index 7c65f43f5a..c30fff92e4 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java @@ -68,6 +68,9 @@ class WebSocketServerProtocolHandshakeHandler public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { ctx.fireExceptionCaught(future.cause()); + } else { + ctx.fireUserEventTriggered( + WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE); } } });