Merge pull request #118 from veebs/WsPipelineReplace3.2
Back port #115 and #117 to 3.2 branch
This commit is contained in:
commit
e479b3d6b2
@ -47,6 +47,6 @@ public class WebSocketServer {
|
|||||||
// Bind and start to accept incoming connections.
|
// Bind and start to accept incoming connections.
|
||||||
bootstrap.bind(new InetSocketAddress(9000));
|
bootstrap.bind(new InetSocketAddress(9000));
|
||||||
|
|
||||||
System.out.println("Web Socket Server started on 9000. Open your browser and navigate to http://localhost:9000/");
|
System.out.println("Web Socket Server started on localhost:9000.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,11 +72,11 @@ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
// Handshake
|
// Handshake
|
||||||
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
|
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
|
||||||
this.getWebSocketLocation(req), null, false);
|
this.getWebSocketLocation(req), null, false);
|
||||||
this.handshaker = wsFactory.newHandshaker(ctx, req);
|
this.handshaker = wsFactory.newHandshaker(req);
|
||||||
if (this.handshaker == null) {
|
if (this.handshaker == null) {
|
||||||
wsFactory.sendUnsupportedWebSocketVersionResponse(ctx);
|
wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());
|
||||||
} else {
|
} else {
|
||||||
this.handshaker.performOpeningHandshake(ctx, req);
|
this.handshaker.performOpeningHandshake(ctx.getChannel(), req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
.format("Channel %s received %s", ctx.getChannel().getId(), frame.getClass().getSimpleName()));
|
.format("Channel %s received %s", ctx.getChannel().getId(), frame.getClass().getSimpleName()));
|
||||||
|
|
||||||
if (frame instanceof CloseWebSocketFrame) {
|
if (frame instanceof CloseWebSocketFrame) {
|
||||||
this.handshaker.performClosingHandshake(ctx, (CloseWebSocketFrame) frame);
|
this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame);
|
||||||
} else if (frame instanceof PingWebSocketFrame) {
|
} else if (frame instanceof PingWebSocketFrame) {
|
||||||
ctx.getChannel().write(
|
ctx.getChannel().write(
|
||||||
new PongWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData()));
|
new PongWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData()));
|
||||||
@ -129,4 +129,4 @@ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
private String getWebSocketLocation(HttpRequest req) {
|
private String getWebSocketLocation(HttpRequest req) {
|
||||||
return "ws://" + req.getHeader(HttpHeaders.Names.HOST);
|
return "ws://" + req.getHeader(HttpHeaders.Names.HOST);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,7 +26,6 @@ import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
|
|||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class WebSocketServerPipelineFactory implements ChannelPipelineFactory {
|
public class WebSocketServerPipelineFactory implements ChannelPipelineFactory {
|
||||||
@Override
|
|
||||||
public ChannelPipeline getPipeline() throws Exception {
|
public ChannelPipeline getPipeline() throws Exception {
|
||||||
// Create a default pipeline implementation.
|
// Create a default pipeline implementation.
|
||||||
ChannelPipeline pipeline = pipeline();
|
ChannelPipeline pipeline = pipeline();
|
||||||
|
@ -55,8 +55,9 @@ public class App {
|
|||||||
MyCallbackHandler callbackHandler = new MyCallbackHandler();
|
MyCallbackHandler callbackHandler = new MyCallbackHandler();
|
||||||
WebSocketClientFactory factory = new WebSocketClientFactory();
|
WebSocketClientFactory factory = new WebSocketClientFactory();
|
||||||
|
|
||||||
// Connect with spec version 17 (try changing it to V10 or V00 and it will
|
// Connect with spec version 17. You can change it to V10 or V00.
|
||||||
// still work ... fingers crossed ;-)
|
// If you change it to V00, ping is not supported and remember to change HttpResponseDecoder to
|
||||||
|
// WebSocketHttpResponseDecoder in the pipeline.
|
||||||
WebSocketClient client = factory.newClient(new URI("ws://localhost:8080/websocket"),
|
WebSocketClient client = factory.newClient(new URI("ws://localhost:8080/websocket"),
|
||||||
WebSocketSpecificationVersion.V17, callbackHandler);
|
WebSocketSpecificationVersion.V17, callbackHandler);
|
||||||
|
|
||||||
@ -96,19 +97,16 @@ public class App {
|
|||||||
public MyCallbackHandler() {
|
public MyCallbackHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConnect(WebSocketClient client) {
|
public void onConnect(WebSocketClient client) {
|
||||||
System.out.println("WebSocket Client connected!");
|
System.out.println("WebSocket Client connected!");
|
||||||
connected = true;
|
connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisconnect(WebSocketClient client) {
|
public void onDisconnect(WebSocketClient client) {
|
||||||
System.out.println("WebSocket Client disconnected!");
|
System.out.println("WebSocket Client disconnected!");
|
||||||
connected = false;
|
connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(WebSocketClient client, WebSocketFrame frame) {
|
public void onMessage(WebSocketClient client, WebSocketFrame frame) {
|
||||||
if (frame instanceof TextWebSocketFrame) {
|
if (frame instanceof TextWebSocketFrame) {
|
||||||
TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
|
TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
|
||||||
@ -121,7 +119,6 @@ public class App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable t) {
|
public void onError(Throwable t) {
|
||||||
System.out.println("WebSocket Client error " + t.toString());
|
System.out.println("WebSocket Client error " + t.toString());
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import org.jboss.netty.channel.ChannelPipelineFactory;
|
|||||||
import org.jboss.netty.channel.Channels;
|
import org.jboss.netty.channel.Channels;
|
||||||
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
|
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequestEncoder;
|
import org.jboss.netty.handler.codec.http.HttpRequestEncoder;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
|
||||||
import org.jboss.netty.handler.codec.http.websocketx.WebSocketSpecificationVersion;
|
import org.jboss.netty.handler.codec.http.websocketx.WebSocketSpecificationVersion;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -69,10 +70,13 @@ public class WebSocketClientFactory {
|
|||||||
|
|
||||||
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
|
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelPipeline getPipeline() throws Exception {
|
public ChannelPipeline getPipeline() throws Exception {
|
||||||
ChannelPipeline pipeline = Channels.pipeline();
|
ChannelPipeline pipeline = Channels.pipeline();
|
||||||
pipeline.addLast("decoder", new WebSocketHttpResponseDecoder());
|
|
||||||
|
// If you wish to support HyBi V00, you need to use WebSocketHttpResponseDecoder instead for
|
||||||
|
// HttpResponseDecoder.
|
||||||
|
pipeline.addLast("decoder", new HttpResponseDecoder());
|
||||||
|
|
||||||
pipeline.addLast("encoder", new HttpRequestEncoder());
|
pipeline.addLast("encoder", new HttpRequestEncoder());
|
||||||
pipeline.addLast("ws-handler", clientHandler);
|
pipeline.addLast("ws-handler", clientHandler);
|
||||||
return pipeline;
|
return pipeline;
|
||||||
|
@ -66,7 +66,7 @@ public class WebSocketClientHandler extends SimpleChannelUpstreamHandler impleme
|
|||||||
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
|
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
|
||||||
channel = e.getChannel();
|
channel = e.getChannel();
|
||||||
this.handshaker = new WebSocketClientHandshakerFactory().newHandshaker(url, version, null, false);
|
this.handshaker = new WebSocketClientHandshakerFactory().newHandshaker(url, version, null, false);
|
||||||
handshaker.performOpeningHandshake(ctx, channel);
|
handshaker.performOpeningHandshake(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -77,7 +77,7 @@ public class WebSocketClientHandler extends SimpleChannelUpstreamHandler impleme
|
|||||||
@Override
|
@Override
|
||||||
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
||||||
if (!handshaker.isOpeningHandshakeCompleted()) {
|
if (!handshaker.isOpeningHandshakeCompleted()) {
|
||||||
handshaker.performClosingHandshake(ctx, (HttpResponse) e.getMessage());
|
handshaker.performClosingHandshake(ctx.getChannel(), (HttpResponse) e.getMessage());
|
||||||
callback.onConnect(this);
|
callback.onConnect(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -99,17 +99,14 @@ public class WebSocketClientHandler extends SimpleChannelUpstreamHandler impleme
|
|||||||
e.getChannel().close();
|
e.getChannel().close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelFuture connect() {
|
public ChannelFuture connect() {
|
||||||
return bootstrap.connect(new InetSocketAddress(url.getHost(), url.getPort()));
|
return bootstrap.connect(new InetSocketAddress(url.getHost(), url.getPort()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelFuture disconnect() {
|
public ChannelFuture disconnect() {
|
||||||
return channel.close();
|
return channel.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelFuture send(WebSocketFrame frame) {
|
public ChannelFuture send(WebSocketFrame frame) {
|
||||||
return channel.write(frame);
|
return channel.write(frame);
|
||||||
}
|
}
|
||||||
@ -121,4 +118,4 @@ public class WebSocketClientHandler extends SimpleChannelUpstreamHandler impleme
|
|||||||
public void setUrl(URI url) {
|
public void setUrl(URI url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -92,11 +92,11 @@ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
// Handshake
|
// Handshake
|
||||||
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
|
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
|
||||||
this.getWebSocketLocation(req), null, false);
|
this.getWebSocketLocation(req), null, false);
|
||||||
this.handshaker = wsFactory.newHandshaker(ctx, req);
|
this.handshaker = wsFactory.newHandshaker(req);
|
||||||
if (this.handshaker == null) {
|
if (this.handshaker == null) {
|
||||||
wsFactory.sendUnsupportedWebSocketVersionResponse(ctx);
|
wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());
|
||||||
} else {
|
} else {
|
||||||
this.handshaker.performOpeningHandshake(ctx, req);
|
this.handshaker.performOpeningHandshake(ctx.getChannel(), req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
|
|
||||||
// Check for closing frame
|
// Check for closing frame
|
||||||
if (frame instanceof CloseWebSocketFrame) {
|
if (frame instanceof CloseWebSocketFrame) {
|
||||||
this.handshaker.performClosingHandshake(ctx, (CloseWebSocketFrame) frame);
|
this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame);
|
||||||
return;
|
return;
|
||||||
} else if (frame instanceof PingWebSocketFrame) {
|
} else if (frame instanceof PingWebSocketFrame) {
|
||||||
ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
|
ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
|
||||||
@ -143,4 +143,4 @@ public class WebSocketServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
private String getWebSocketLocation(HttpRequest req) {
|
private String getWebSocketLocation(HttpRequest req) {
|
||||||
return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
|
return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,7 +26,6 @@ import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
|
|||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class WebSocketServerPipelineFactory implements ChannelPipelineFactory {
|
public class WebSocketServerPipelineFactory implements ChannelPipelineFactory {
|
||||||
@Override
|
|
||||||
public ChannelPipeline getPipeline() throws Exception {
|
public ChannelPipeline getPipeline() throws Exception {
|
||||||
// Create a default pipeline implementation.
|
// Create a default pipeline implementation.
|
||||||
ChannelPipeline pipeline = pipeline();
|
ChannelPipeline pipeline = pipeline();
|
||||||
|
@ -92,11 +92,11 @@ public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
// Handshake
|
// Handshake
|
||||||
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
|
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
|
||||||
this.getWebSocketLocation(req), null, false);
|
this.getWebSocketLocation(req), null, false);
|
||||||
this.handshaker = wsFactory.newHandshaker(ctx, req);
|
this.handshaker = wsFactory.newHandshaker(req);
|
||||||
if (this.handshaker == null) {
|
if (this.handshaker == null) {
|
||||||
wsFactory.sendUnsupportedWebSocketVersionResponse(ctx);
|
wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());
|
||||||
} else {
|
} else {
|
||||||
this.handshaker.performOpeningHandshake(ctx, req);
|
this.handshaker.performOpeningHandshake(ctx.getChannel(), req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
|
|
||||||
// Check for closing frame
|
// Check for closing frame
|
||||||
if (frame instanceof CloseWebSocketFrame) {
|
if (frame instanceof CloseWebSocketFrame) {
|
||||||
this.handshaker.performClosingHandshake(ctx, (CloseWebSocketFrame) frame);
|
this.handshaker.performClosingHandshake(ctx.getChannel(), (CloseWebSocketFrame) frame);
|
||||||
return;
|
return;
|
||||||
} else if (frame instanceof PingWebSocketFrame) {
|
} else if (frame instanceof PingWebSocketFrame) {
|
||||||
ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
|
ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
|
||||||
@ -143,4 +143,4 @@ public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler {
|
|||||||
private String getWebSocketLocation(HttpRequest req) {
|
private String getWebSocketLocation(HttpRequest req) {
|
||||||
return "wss://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
|
return "wss://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,7 +29,6 @@ import org.jboss.netty.handler.ssl.SslHandler;
|
|||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class WebSocketSslServerPipelineFactory implements ChannelPipelineFactory {
|
public class WebSocketSslServerPipelineFactory implements ChannelPipelineFactory {
|
||||||
@Override
|
|
||||||
public ChannelPipeline getPipeline() throws Exception {
|
public ChannelPipeline getPipeline() throws Exception {
|
||||||
// Create a default pipeline implementation.
|
// Create a default pipeline implementation.
|
||||||
ChannelPipeline pipeline = pipeline();
|
ChannelPipeline pipeline = pipeline();
|
||||||
|
@ -22,7 +22,6 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
import org.jboss.netty.buffer.ChannelBuffer;
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
import org.jboss.netty.buffer.ChannelBuffers;
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
import org.jboss.netty.channel.Channel;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.jboss.netty.handler.codec.base64.Base64;
|
import org.jboss.netty.handler.codec.base64.Base64;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
import org.jboss.netty.util.CharsetUtil;
|
import org.jboss.netty.util.CharsetUtil;
|
||||||
@ -114,22 +113,20 @@ public abstract class WebSocketClientHandshaker {
|
|||||||
/**
|
/**
|
||||||
* Performs the opening handshake
|
* Performs the opening handshake
|
||||||
*
|
*
|
||||||
* @param ctx
|
|
||||||
* Channel context
|
|
||||||
* @param channel
|
* @param channel
|
||||||
* Channel
|
* Channel
|
||||||
*/
|
*/
|
||||||
public abstract void performOpeningHandshake(ChannelHandlerContext ctx, Channel channel);
|
public abstract void performOpeningHandshake(Channel channel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the closing handshake
|
* Performs the closing handshake
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param response
|
* @param response
|
||||||
* HTTP response containing the closing handshake details
|
* HTTP response containing the closing handshake details
|
||||||
*/
|
*/
|
||||||
public abstract void performClosingHandshake(ChannelHandlerContext ctx, HttpResponse response) throws WebSocketHandshakeException;
|
public abstract void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs an MD5 hash
|
* Performs an MD5 hash
|
||||||
@ -204,4 +201,4 @@ public abstract class WebSocketClientHandshaker {
|
|||||||
protected int createRandomNumber(int min, int max) {
|
protected int createRandomNumber(int min, int max) {
|
||||||
return (int) (Math.random() * max + min);
|
return (int) (Math.random() * max + min);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,13 +21,14 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
import org.jboss.netty.buffer.ChannelBuffers;
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
import org.jboss.netty.channel.Channel;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
||||||
import org.jboss.netty.handler.codec.http.HttpMethod;
|
import org.jboss.netty.handler.codec.http.HttpMethod;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestEncoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import org.jboss.netty.handler.codec.http.HttpVersion;
|
import org.jboss.netty.handler.codec.http.HttpVersion;
|
||||||
|
|
||||||
@ -81,13 +82,11 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
* ^n:ds[4U
|
* ^n:ds[4U
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
|
||||||
* Channel context
|
|
||||||
* @param channel
|
* @param channel
|
||||||
* Channel into which we can write our request
|
* Channel into which we can write our request
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performOpeningHandshake(ChannelHandlerContext ctx, Channel channel) {
|
public void performOpeningHandshake(Channel channel) {
|
||||||
// Make keys
|
// Make keys
|
||||||
int spaces1 = createRandomNumber(1, 12);
|
int spaces1 = createRandomNumber(1, 12);
|
||||||
int spaces2 = createRandomNumber(1, 12);
|
int spaces2 = createRandomNumber(1, 12);
|
||||||
@ -147,7 +146,7 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
|
|
||||||
channel.write(request);
|
channel.write(request);
|
||||||
|
|
||||||
ctx.getPipeline().replace("encoder", "ws-encoder", new WebSocket00FrameEncoder());
|
channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket00FrameEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,15 +165,15 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
* 8jKS'y:G*Co,Wxa-
|
* 8jKS'y:G*Co,Wxa-
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param response
|
* @param response
|
||||||
* HTTP response returned from the server for the request sent by
|
* HTTP response returned from the server for the request sent by
|
||||||
* beginOpeningHandshake00().
|
* beginOpeningHandshake00().
|
||||||
* @throws WebSocketHandshakeException
|
* @throws WebSocketHandshakeException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performClosingHandshake(ChannelHandlerContext ctx, HttpResponse response) throws WebSocketHandshakeException {
|
public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException {
|
||||||
final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake");
|
final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake");
|
||||||
|
|
||||||
if (!response.getStatus().equals(status)) {
|
if (!response.getStatus().equals(status)) {
|
||||||
@ -199,7 +198,7 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
String protocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
|
||||||
this.setSubProtocolResponse(protocol);
|
this.setSubProtocolResponse(protocol);
|
||||||
|
|
||||||
ctx.getPipeline().replace("decoder", "ws-decoder", new WebSocket00FrameDecoder());
|
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", new WebSocket00FrameDecoder());
|
||||||
|
|
||||||
this.setOpenningHandshakeCompleted(true);
|
this.setOpenningHandshakeCompleted(true);
|
||||||
}
|
}
|
||||||
@ -238,4 +237,4 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -18,13 +18,14 @@ package org.jboss.netty.handler.codec.http.websocketx;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jboss.netty.channel.Channel;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
||||||
import org.jboss.netty.handler.codec.http.HttpMethod;
|
import org.jboss.netty.handler.codec.http.HttpMethod;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestEncoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import org.jboss.netty.handler.codec.http.HttpVersion;
|
import org.jboss.netty.handler.codec.http.HttpVersion;
|
||||||
import org.jboss.netty.logging.InternalLogger;
|
import org.jboss.netty.logging.InternalLogger;
|
||||||
@ -90,13 +91,11 @@ public class WebSocketClientHandshaker10 extends WebSocketClientHandshaker {
|
|||||||
* Sec-WebSocket-Version: 8
|
* Sec-WebSocket-Version: 8
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
|
||||||
* Channel context
|
|
||||||
* @param channel
|
* @param channel
|
||||||
* Channel into which we can write our request
|
* Channel into which we can write our request
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performOpeningHandshake(ChannelHandlerContext ctx, Channel channel) {
|
public void performOpeningHandshake(Channel channel) {
|
||||||
// Get path
|
// Get path
|
||||||
URI wsURL = this.getWebSocketURL();
|
URI wsURL = this.getWebSocketURL();
|
||||||
String path = wsURL.getPath();
|
String path = wsURL.getPath();
|
||||||
@ -130,7 +129,7 @@ public class WebSocketClientHandshaker10 extends WebSocketClientHandshaker {
|
|||||||
|
|
||||||
channel.write(request);
|
channel.write(request);
|
||||||
|
|
||||||
ctx.getPipeline().replace("encoder", "ws-encoder", new WebSocket08FrameEncoder(true));
|
channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket08FrameEncoder(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,15 +145,15 @@ public class WebSocketClientHandshaker10 extends WebSocketClientHandshaker {
|
|||||||
* Sec-WebSocket-Protocol: chat
|
* Sec-WebSocket-Protocol: chat
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param response
|
* @param response
|
||||||
* HTTP response returned from the server for the request sent by
|
* HTTP response returned from the server for the request sent by
|
||||||
* beginOpeningHandshake00().
|
* beginOpeningHandshake00().
|
||||||
* @throws WebSocketHandshakeException
|
* @throws WebSocketHandshakeException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performClosingHandshake(ChannelHandlerContext ctx, HttpResponse response) throws WebSocketHandshakeException {
|
public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException {
|
||||||
final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols");
|
final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols");
|
||||||
|
|
||||||
if (!response.getStatus().equals(status)) {
|
if (!response.getStatus().equals(status)) {
|
||||||
@ -176,9 +175,9 @@ public class WebSocketClientHandshaker10 extends WebSocketClientHandshaker {
|
|||||||
throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, this.expectedChallengeResponseString));
|
throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, this.expectedChallengeResponseString));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.getPipeline().replace("decoder", "ws-decoder", new WebSocket08FrameDecoder(false, this.allowExtensions));
|
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", new WebSocket08FrameDecoder(false, this.allowExtensions));
|
||||||
|
|
||||||
this.setOpenningHandshakeCompleted(true);
|
this.setOpenningHandshakeCompleted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -18,13 +18,14 @@ package org.jboss.netty.handler.codec.http.websocketx;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jboss.netty.channel.Channel;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
||||||
import org.jboss.netty.handler.codec.http.HttpMethod;
|
import org.jboss.netty.handler.codec.http.HttpMethod;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestEncoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import org.jboss.netty.handler.codec.http.HttpVersion;
|
import org.jboss.netty.handler.codec.http.HttpVersion;
|
||||||
import org.jboss.netty.logging.InternalLogger;
|
import org.jboss.netty.logging.InternalLogger;
|
||||||
@ -90,13 +91,11 @@ public class WebSocketClientHandshaker17 extends WebSocketClientHandshaker {
|
|||||||
* Sec-WebSocket-Version: 13
|
* Sec-WebSocket-Version: 13
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
|
||||||
* Channel context
|
|
||||||
* @param channel
|
* @param channel
|
||||||
* Channel into which we can write our request
|
* Channel into which we can write our request
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performOpeningHandshake(ChannelHandlerContext ctx, Channel channel) {
|
public void performOpeningHandshake(Channel channel) {
|
||||||
// Get path
|
// Get path
|
||||||
URI wsURL = this.getWebSocketURL();
|
URI wsURL = this.getWebSocketURL();
|
||||||
String path = wsURL.getPath();
|
String path = wsURL.getPath();
|
||||||
@ -130,7 +129,7 @@ public class WebSocketClientHandshaker17 extends WebSocketClientHandshaker {
|
|||||||
|
|
||||||
channel.write(request);
|
channel.write(request);
|
||||||
|
|
||||||
ctx.getPipeline().replace("encoder", "ws-encoder", new WebSocket13FrameEncoder(true));
|
channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket13FrameEncoder(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,15 +145,15 @@ public class WebSocketClientHandshaker17 extends WebSocketClientHandshaker {
|
|||||||
* Sec-WebSocket-Protocol: chat
|
* Sec-WebSocket-Protocol: chat
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param response
|
* @param response
|
||||||
* HTTP response returned from the server for the request sent by
|
* HTTP response returned from the server for the request sent by
|
||||||
* beginOpeningHandshake00().
|
* beginOpeningHandshake00().
|
||||||
* @throws WebSocketHandshakeException
|
* @throws WebSocketHandshakeException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performClosingHandshake(ChannelHandlerContext ctx, HttpResponse response) throws WebSocketHandshakeException {
|
public void performClosingHandshake(Channel channel, HttpResponse response) throws WebSocketHandshakeException {
|
||||||
final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols");
|
final HttpResponseStatus status = new HttpResponseStatus(101, "Switching Protocols");
|
||||||
|
|
||||||
if (!response.getStatus().equals(status)) {
|
if (!response.getStatus().equals(status)) {
|
||||||
@ -176,9 +175,9 @@ public class WebSocketClientHandshaker17 extends WebSocketClientHandshaker {
|
|||||||
throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, this.expectedChallengeResponseString));
|
throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, this.expectedChallengeResponseString));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.getPipeline().replace("decoder", "ws-decoder", new WebSocket13FrameDecoder(false, this.allowExtensions));
|
channel.getPipeline().replace(HttpResponseDecoder.class, "ws-decoder", new WebSocket13FrameDecoder(false, this.allowExtensions));
|
||||||
|
|
||||||
this.setOpenningHandshakeCompleted(true);
|
this.setOpenningHandshakeCompleted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -20,14 +20,11 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
|
|
||||||
import org.jboss.netty.buffer.ChannelBuffer;
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
import org.jboss.netty.buffer.ChannelBuffers;
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.handler.codec.base64.Base64;
|
import org.jboss.netty.handler.codec.base64.Base64;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
import org.jboss.netty.util.CharsetUtil;
|
import org.jboss.netty.util.CharsetUtil;
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for server side web socket opening and closing handshakes
|
|
||||||
*/
|
|
||||||
public abstract class WebSocketServerHandshaker {
|
public abstract class WebSocketServerHandshaker {
|
||||||
|
|
||||||
private String webSocketURL;
|
private String webSocketURL;
|
||||||
@ -40,7 +37,7 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor specifying the destination web socket location
|
* Constructor specifying the destination web socket location
|
||||||
*
|
*
|
||||||
* @param webSocketURL
|
* @param webSocketURL
|
||||||
* URL for web socket communications. e.g
|
* URL for web socket communications. e.g
|
||||||
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
@ -96,28 +93,28 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the opening handshake
|
* Performs the opening handshake
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Context
|
* Channel
|
||||||
* @param req
|
* @param req
|
||||||
* HTTP Request
|
* HTTP Request
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
public abstract void performOpeningHandshake(ChannelHandlerContext ctx, HttpRequest req);
|
public abstract void performOpeningHandshake(Channel channel, HttpRequest req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the closing handshake
|
* Performs the closing handshake
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Context
|
* Channel
|
||||||
* @param frame
|
* @param frame
|
||||||
* Closing Frame that was received
|
* Closing Frame that was received
|
||||||
*/
|
*/
|
||||||
public abstract void performClosingHandshake(ChannelHandlerContext ctx, CloseWebSocketFrame frame);
|
public abstract void performClosingHandshake(Channel channel, CloseWebSocketFrame frame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs an MD5 hash
|
* Performs an MD5 hash
|
||||||
*
|
*
|
||||||
* @param bytes
|
* @param bytes
|
||||||
* Data to hash
|
* Data to hash
|
||||||
* @return Hashed data
|
* @return Hashed data
|
||||||
@ -133,7 +130,7 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SHA-1 hashing. Instance this we think it is not thread safe
|
* SHA-1 hashing. Instance this we think it is not thread safe
|
||||||
*
|
*
|
||||||
* @param bytes
|
* @param bytes
|
||||||
* byte to hash
|
* byte to hash
|
||||||
* @return hashed
|
* @return hashed
|
||||||
@ -149,7 +146,7 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Base 64 encoding
|
* Base 64 encoding
|
||||||
*
|
*
|
||||||
* @param bytes
|
* @param bytes
|
||||||
* Bytes to encode
|
* Bytes to encode
|
||||||
* @return encoded string
|
* @return encoded string
|
||||||
@ -161,7 +158,7 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the first matching supported sub protocol
|
* Selects the first matching supported sub protocol
|
||||||
*
|
*
|
||||||
* @param requestedSubProtocol
|
* @param requestedSubProtocol
|
||||||
* CSV of protocols to be supported. e.g. "chat, superchat"
|
* CSV of protocols to be supported. e.g. "chat, superchat"
|
||||||
* @return First matching supported sub protocol. Null if not found.
|
* @return First matching supported sub protocol. Null if not found.
|
||||||
@ -185,4 +182,4 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
// No match found
|
// No match found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,11 +32,14 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
|
|
||||||
import org.jboss.netty.buffer.ChannelBuffer;
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
import org.jboss.netty.buffer.ChannelBuffers;
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelPipeline;
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
|
||||||
@ -60,7 +63,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor specifying the destination web socket location
|
* Constructor specifying the destination web socket location
|
||||||
*
|
*
|
||||||
* @param webSocketURL
|
* @param webSocketURL
|
||||||
* URL for web socket communications. e.g
|
* URL for web socket communications. e.g
|
||||||
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
@ -82,11 +85,11 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
* href="http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75"
|
* href="http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75"
|
||||||
* >hixie-75</a>.
|
* >hixie-75</a>.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Browser request to the server:
|
* Browser request to the server:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* GET /demo HTTP/1.1
|
* GET /demo HTTP/1.1
|
||||||
* Upgrade: WebSocket
|
* Upgrade: WebSocket
|
||||||
@ -95,14 +98,14 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
* Origin: http://example.com
|
* Origin: http://example.com
|
||||||
* Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
|
* Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
|
||||||
* Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
|
* Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
|
||||||
*
|
*
|
||||||
* ^n:ds[4U
|
* ^n:ds[4U
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Server response:
|
* Server response:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* HTTP/1.1 101 WebSocket Protocol Handshake
|
* HTTP/1.1 101 WebSocket Protocol Handshake
|
||||||
* Upgrade: WebSocket
|
* Upgrade: WebSocket
|
||||||
@ -110,21 +113,21 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
* Sec-WebSocket-Origin: http://example.com
|
* Sec-WebSocket-Origin: http://example.com
|
||||||
* Sec-WebSocket-Location: ws://example.com/demo
|
* Sec-WebSocket-Location: ws://example.com/demo
|
||||||
* Sec-WebSocket-Protocol: sample
|
* Sec-WebSocket-Protocol: sample
|
||||||
*
|
*
|
||||||
* 8jKS'y:G*Co,Wxa-
|
* 8jKS'y:G*Co,Wxa-
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param req
|
* @param req
|
||||||
* HTTP request
|
* HTTP request
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performOpeningHandshake(ChannelHandlerContext ctx, HttpRequest req) {
|
public void performOpeningHandshake(Channel channel, HttpRequest req) {
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("Channel %s web socket spec version 00 handshake", ctx.getChannel().getId()));
|
logger.debug(String.format("Channel %s web socket spec version 00 handshake", channel.getId()));
|
||||||
}
|
}
|
||||||
this.setVersion(WebSocketSpecificationVersion.V00);
|
this.setVersion(WebSocketSpecificationVersion.V00);
|
||||||
|
|
||||||
@ -174,25 +177,25 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade the connection and send the handshake response.
|
// Upgrade the connection and send the handshake response.
|
||||||
ChannelPipeline p = ctx.getChannel().getPipeline();
|
ChannelPipeline p = channel.getPipeline();
|
||||||
p.remove("aggregator");
|
p.remove(HttpChunkAggregator.class);
|
||||||
p.replace("decoder", "wsdecoder", new WebSocket00FrameDecoder());
|
p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket00FrameDecoder());
|
||||||
|
|
||||||
ctx.getChannel().write(res);
|
channel.write(res);
|
||||||
|
|
||||||
p.replace("encoder", "wsencoder", new WebSocket00FrameEncoder());
|
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Echo back the closing frame
|
* Echo back the closing frame
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param frame
|
* @param frame
|
||||||
* Web Socket frame that was received
|
* Web Socket frame that was received
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performClosingHandshake(ChannelHandlerContext ctx, CloseWebSocketFrame frame) {
|
public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) {
|
||||||
ctx.getChannel().write(frame);
|
channel.write(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,13 +20,16 @@ import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
|||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelFuture;
|
import org.jboss.netty.channel.ChannelFuture;
|
||||||
import org.jboss.netty.channel.ChannelFutureListener;
|
import org.jboss.netty.channel.ChannelFutureListener;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.jboss.netty.channel.ChannelPipeline;
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
||||||
import org.jboss.netty.logging.InternalLogger;
|
import org.jboss.netty.logging.InternalLogger;
|
||||||
@ -51,7 +54,7 @@ public class WebSocketServerHandshaker10 extends WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor specifying the destination web socket location
|
* Constructor specifying the destination web socket location
|
||||||
*
|
*
|
||||||
* @param webSocketURL
|
* @param webSocketURL
|
||||||
* URL for web socket communications. e.g
|
* URL for web socket communications. e.g
|
||||||
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
@ -73,11 +76,11 @@ public class WebSocketServerHandshaker10 extends WebSocketServerHandshaker {
|
|||||||
* "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-08">HyBi
|
* "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-08">HyBi
|
||||||
* version 8 to 10</a>. Version 8, 9 and 10 share the same wire protocol.
|
* version 8 to 10</a>. Version 8, 9 and 10 share the same wire protocol.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Browser request to the server:
|
* Browser request to the server:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* GET /chat HTTP/1.1
|
* GET /chat HTTP/1.1
|
||||||
* Host: server.example.com
|
* Host: server.example.com
|
||||||
@ -88,11 +91,11 @@ public class WebSocketServerHandshaker10 extends WebSocketServerHandshaker {
|
|||||||
* Sec-WebSocket-Protocol: chat, superchat
|
* Sec-WebSocket-Protocol: chat, superchat
|
||||||
* Sec-WebSocket-Version: 8
|
* Sec-WebSocket-Version: 8
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Server response:
|
* Server response:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* HTTP/1.1 101 Switching Protocols
|
* HTTP/1.1 101 Switching Protocols
|
||||||
* Upgrade: websocket
|
* Upgrade: websocket
|
||||||
@ -100,18 +103,18 @@ public class WebSocketServerHandshaker10 extends WebSocketServerHandshaker {
|
|||||||
* Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
* Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
||||||
* Sec-WebSocket-Protocol: chat
|
* Sec-WebSocket-Protocol: chat
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param req
|
* @param req
|
||||||
* HTTP request
|
* HTTP request
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performOpeningHandshake(ChannelHandlerContext ctx, HttpRequest req) {
|
public void performOpeningHandshake(Channel channel, HttpRequest req) {
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("Channel %s web socket spec version 10 handshake", ctx.getChannel().getId()));
|
logger.debug(String.format("Channel %s web socket spec version 10 handshake", channel.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols"));
|
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols"));
|
||||||
@ -139,28 +142,28 @@ public class WebSocketServerHandshaker10 extends WebSocketServerHandshaker {
|
|||||||
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, this.selectSubProtocol(protocol));
|
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, this.selectSubProtocol(protocol));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.getChannel().write(res);
|
channel.write(res);
|
||||||
|
|
||||||
// Upgrade the connection and send the handshake response.
|
// Upgrade the connection and send the handshake response.
|
||||||
ChannelPipeline p = ctx.getChannel().getPipeline();
|
ChannelPipeline p = channel.getPipeline();
|
||||||
p.remove("aggregator");
|
p.remove(HttpChunkAggregator.class);
|
||||||
p.replace("decoder", "wsdecoder", new WebSocket08FrameDecoder(true, this.allowExtensions));
|
p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket08FrameDecoder(true, this.allowExtensions));
|
||||||
p.replace("encoder", "wsencoder", new WebSocket08FrameEncoder(false));
|
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Echo back the closing frame and close the connection
|
* Echo back the closing frame and close the connection
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param frame
|
* @param frame
|
||||||
* Web Socket frame that was received
|
* Web Socket frame that was received
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performClosingHandshake(ChannelHandlerContext ctx, CloseWebSocketFrame frame) {
|
public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) {
|
||||||
ChannelFuture f = ctx.getChannel().write(frame);
|
ChannelFuture f = channel.write(frame);
|
||||||
f.addListener(ChannelFutureListener.CLOSE);
|
f.addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -20,13 +20,16 @@ import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
|||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelFuture;
|
import org.jboss.netty.channel.ChannelFuture;
|
||||||
import org.jboss.netty.channel.ChannelFutureListener;
|
import org.jboss.netty.channel.ChannelFutureListener;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.jboss.netty.channel.ChannelPipeline;
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
|
||||||
import org.jboss.netty.logging.InternalLogger;
|
import org.jboss.netty.logging.InternalLogger;
|
||||||
@ -51,7 +54,7 @@ public class WebSocketServerHandshaker17 extends WebSocketServerHandshaker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor specifying the destination web socket location
|
* Constructor specifying the destination web socket location
|
||||||
*
|
*
|
||||||
* @param webSocketURL
|
* @param webSocketURL
|
||||||
* URL for web socket communications. e.g
|
* URL for web socket communications. e.g
|
||||||
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
@ -73,11 +76,11 @@ public class WebSocketServerHandshaker17 extends WebSocketServerHandshaker {
|
|||||||
* "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17">HyBi
|
* "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17">HyBi
|
||||||
* versions 13-17</a>. Versions 13-17 share the same wire protocol.
|
* versions 13-17</a>. Versions 13-17 share the same wire protocol.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Browser request to the server:
|
* Browser request to the server:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* GET /chat HTTP/1.1
|
* GET /chat HTTP/1.1
|
||||||
* Host: server.example.com
|
* Host: server.example.com
|
||||||
@ -88,11 +91,11 @@ public class WebSocketServerHandshaker17 extends WebSocketServerHandshaker {
|
|||||||
* Sec-WebSocket-Protocol: chat, superchat
|
* Sec-WebSocket-Protocol: chat, superchat
|
||||||
* Sec-WebSocket-Version: 13
|
* Sec-WebSocket-Version: 13
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Server response:
|
* Server response:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* HTTP/1.1 101 Switching Protocols
|
* HTTP/1.1 101 Switching Protocols
|
||||||
* Upgrade: websocket
|
* Upgrade: websocket
|
||||||
@ -100,18 +103,18 @@ public class WebSocketServerHandshaker17 extends WebSocketServerHandshaker {
|
|||||||
* Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
* Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
||||||
* Sec-WebSocket-Protocol: chat
|
* Sec-WebSocket-Protocol: chat
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param req
|
* @param req
|
||||||
* HTTP request
|
* HTTP request
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performOpeningHandshake(ChannelHandlerContext ctx, HttpRequest req) {
|
public void performOpeningHandshake(Channel channel, HttpRequest req) {
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("Channel %s web socket spec version 17 handshake", ctx.getChannel().getId()));
|
logger.debug(String.format("Channel %s web socket spec version 17 handshake", channel.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols"));
|
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, "Switching Protocols"));
|
||||||
@ -139,28 +142,28 @@ public class WebSocketServerHandshaker17 extends WebSocketServerHandshaker {
|
|||||||
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, this.selectSubProtocol(protocol));
|
res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, this.selectSubProtocol(protocol));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.getChannel().write(res);
|
channel.write(res);
|
||||||
|
|
||||||
// Upgrade the connection and send the handshake response.
|
// Upgrade the connection and send the handshake response.
|
||||||
ChannelPipeline p = ctx.getChannel().getPipeline();
|
ChannelPipeline p = channel.getPipeline();
|
||||||
p.remove("aggregator");
|
p.remove(HttpChunkAggregator.class);
|
||||||
p.replace("decoder", "wsdecoder", new WebSocket13FrameDecoder(true, this.allowExtensions));
|
p.replace(HttpRequestDecoder.class, "wsdecoder", new WebSocket13FrameDecoder(true, this.allowExtensions));
|
||||||
p.replace("encoder", "wsencoder", new WebSocket13FrameEncoder(false));
|
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Echo back the closing frame and close the connection
|
* Echo back the closing frame and close the connection
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Channel context
|
* Channel
|
||||||
* @param frame
|
* @param frame
|
||||||
* Web Socket frame that was received
|
* Web Socket frame that was received
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performClosingHandshake(ChannelHandlerContext ctx, CloseWebSocketFrame frame) {
|
public void performClosingHandshake(Channel channel, CloseWebSocketFrame frame) {
|
||||||
ChannelFuture f = ctx.getChannel().write(frame);
|
ChannelFuture f = channel.write(frame);
|
||||||
f.addListener(ChannelFutureListener.CLOSE);
|
f.addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jboss.netty.handler.codec.http.websocketx;
|
package org.jboss.netty.handler.codec.http.websocketx;
|
||||||
|
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
@ -36,7 +36,7 @@ public class WebSocketServerHandshakerFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor specifying the destination web socket location
|
* Constructor specifying the destination web socket location
|
||||||
*
|
*
|
||||||
* @param webSocketURL
|
* @param webSocketURL
|
||||||
* URL for web socket communications. e.g
|
* URL for web socket communications. e.g
|
||||||
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
* "ws://myhost.com/mypath". Subsequent web socket frames will be
|
||||||
@ -56,11 +56,11 @@ public class WebSocketServerHandshakerFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instances a new handshaker
|
* Instances a new handshaker
|
||||||
*
|
*
|
||||||
* @return A new WebSocketServerHandshaker for the requested web socket
|
* @return A new WebSocketServerHandshaker for the requested web socket
|
||||||
* version. Null if web socket version is not supported.
|
* version. Null if web socket version is not supported.
|
||||||
*/
|
*/
|
||||||
public WebSocketServerHandshaker newHandshaker(ChannelHandlerContext ctx, HttpRequest req) {
|
public WebSocketServerHandshaker newHandshaker(HttpRequest req) {
|
||||||
|
|
||||||
String version = req.getHeader(Names.SEC_WEBSOCKET_VERSION);
|
String version = req.getHeader(Names.SEC_WEBSOCKET_VERSION);
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
@ -83,16 +83,16 @@ public class WebSocketServerHandshakerFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return that we need cannot not support the web socket version
|
* Return that we need cannot not support the web socket version
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param channel
|
||||||
* Context
|
* Channel
|
||||||
*/
|
*/
|
||||||
public void sendUnsupportedWebSocketVersionResponse(ChannelHandlerContext ctx) {
|
public void sendUnsupportedWebSocketVersionResponse(Channel channel) {
|
||||||
HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(101,
|
HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(101,
|
||||||
"Switching Protocols"));
|
"Switching Protocols"));
|
||||||
res.setStatus(HttpResponseStatus.UPGRADE_REQUIRED);
|
res.setStatus(HttpResponseStatus.UPGRADE_REQUIRED);
|
||||||
res.setHeader(Names.SEC_WEBSOCKET_VERSION, "13");
|
res.setHeader(Names.SEC_WEBSOCKET_VERSION, "13");
|
||||||
ctx.getChannel().write(res);
|
channel.write(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user