[#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.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelStateHandler;
import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpHeaders;
import java.net.URI; import java.net.URI;
@ -30,12 +31,31 @@ import java.net.URI;
* the {@code handleCloseFrames} is {@code false}, default is {@code true}. * 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. * 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 { public class WebSocketClientProtocolHandler extends WebSocketProtocolHandler {
private final WebSocketClientHandshaker handshaker; private final WebSocketClientHandshaker handshaker;
private final boolean handleCloseFrames; 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 * Base constructor
* *

View File

@ -15,6 +15,7 @@
*/ */
package io.netty.handler.codec.http.websocketx; package io.netty.handler.codec.http.websocketx;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelInboundMessageHandlerAdapter;
@ -28,15 +29,27 @@ class WebSocketClientProtocolHandshakeHandler extends ChannelInboundMessageHandl
} }
@Override @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { public void channelActive(final ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx); 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 @Override
public void messageReceived(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { public void messageReceived(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception {
if (!handshaker.isHandshakeComplete()) { if (!handshaker.isHandshakeComplete()) {
handshaker.finishHandshake(ctx.channel(), msg); handshaker.finishHandshake(ctx.channel(), msg);
ctx.fireUserEventTriggered(
WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE);
ctx.pipeline().removeAndForward(this); ctx.pipeline().removeAndForward(this);
return; return;
} }

View File

@ -20,6 +20,7 @@ import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelInboundMessageHandlerAdapter;
import io.netty.channel.ChannelStateHandler;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest; 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 * 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 * 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 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 { 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 = private static final AttributeKey<WebSocketServerHandshaker> HANDSHAKER_ATTR_KEY =
new AttributeKey<WebSocketServerHandshaker>(WebSocketServerHandshaker.class.getName()); new AttributeKey<WebSocketServerHandshaker>(WebSocketServerHandshaker.class.getName());

View File

@ -68,6 +68,9 @@ class WebSocketServerProtocolHandshakeHandler
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) { if (!future.isSuccess()) {
ctx.fireExceptionCaught(future.cause()); ctx.fireExceptionCaught(future.cause());
} else {
ctx.fireUserEventTriggered(
WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE);
} }
} }
}); });