[#1212] Fire handshake status events to notify the user about handshake states

This commit is contained in:
Norman Maurer 2013-03-28 06:57:04 +01:00
parent 4a9ab4f57c
commit a97cca50df
4 changed files with 53 additions and 2 deletions

View File

@ -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
*

View File

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

View File

@ -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 <tt>io.netty.example.http.websocketx.server.WebSocketServer</tt> 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<WebSocketServerHandshaker> HANDSHAKER_ATTR_KEY =
new AttributeKey<WebSocketServerHandshaker>(WebSocketServerHandshaker.class.getName());

View File

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