1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.example.http.websocketx.autobahn;
17
18 import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
19 import static org.jboss.netty.handler.codec.http.HttpMethod.*;
20 import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
21 import static org.jboss.netty.handler.codec.http.HttpVersion.*;
22
23 import org.jboss.netty.buffer.ChannelBuffers;
24 import org.jboss.netty.channel.ChannelFuture;
25 import org.jboss.netty.channel.ChannelFutureListener;
26 import org.jboss.netty.channel.ChannelHandlerContext;
27 import org.jboss.netty.channel.ExceptionEvent;
28 import org.jboss.netty.channel.MessageEvent;
29 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
30 import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
31 import org.jboss.netty.handler.codec.http.HttpHeaders;
32 import org.jboss.netty.handler.codec.http.HttpRequest;
33 import org.jboss.netty.handler.codec.http.HttpResponse;
34 import org.jboss.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
35 import org.jboss.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
36 import org.jboss.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
37 import org.jboss.netty.handler.codec.http.websocketx.PingWebSocketFrame;
38 import org.jboss.netty.handler.codec.http.websocketx.PongWebSocketFrame;
39 import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame;
40 import org.jboss.netty.handler.codec.http.websocketx.WebSocketFrame;
41 import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
42 import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
43 import org.jboss.netty.logging.InternalLogger;
44 import org.jboss.netty.logging.InternalLoggerFactory;
45 import org.jboss.netty.util.CharsetUtil;
46
47
48
49
50 public class AutobahnServerHandler extends SimpleChannelUpstreamHandler {
51 private static final InternalLogger logger = InternalLoggerFactory.getInstance(AutobahnServerHandler.class);
52
53 private WebSocketServerHandshaker handshaker;
54
55 @Override
56 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
57 Object msg = e.getMessage();
58 if (msg instanceof HttpRequest) {
59 handleHttpRequest(ctx, (HttpRequest) msg);
60 } else if (msg instanceof WebSocketFrame) {
61 handleWebSocketFrame(ctx, (WebSocketFrame) msg);
62 }
63 }
64
65 private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
66
67 if (req.getMethod() != GET) {
68 sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));
69 return;
70 }
71
72
73 WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
74 getWebSocketLocation(req), null, false);
75 handshaker = wsFactory.newHandshaker(req);
76 if (handshaker == null) {
77 wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());
78 } else {
79 handshaker.handshake(ctx.getChannel(), req).addListener(WebSocketServerHandshaker.HANDSHAKE_LISTENER);
80 }
81 }
82
83 private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
84 if (logger.isDebugEnabled()) {
85 logger.debug(String
86 .format("Channel %s received %s", ctx.getChannel().getId(), frame.getClass().getSimpleName()));
87 }
88
89
90 if (frame instanceof CloseWebSocketFrame) {
91 handshaker.close(ctx.getChannel(), (CloseWebSocketFrame) frame);
92 } else if (frame instanceof PingWebSocketFrame) {
93 ctx.getChannel().write(
94 new PongWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData()));
95 } else if (frame instanceof TextWebSocketFrame) {
96
97 ctx.getChannel().write(
98 new TextWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData()));
99 } else if (frame instanceof BinaryWebSocketFrame) {
100 ctx.getChannel().write(
101 new BinaryWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData()));
102 } else if (frame instanceof ContinuationWebSocketFrame) {
103 ctx.getChannel().write(
104 new ContinuationWebSocketFrame(frame.isFinalFragment(), frame.getRsv(), frame.getBinaryData()));
105 } else if (frame instanceof PongWebSocketFrame) {
106
107 } else {
108 throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass()
109 .getName()));
110 }
111 }
112
113 private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) {
114
115 if (res.getStatus().getCode() != 200) {
116 res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8));
117 setContentLength(res, res.getContent().readableBytes());
118 }
119
120
121 ChannelFuture f = ctx.getChannel().write(res);
122 if (!isKeepAlive(req) || res.getStatus().getCode() != 200) {
123 f.addListener(ChannelFutureListener.CLOSE);
124 }
125 }
126
127 @Override
128 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
129 e.getCause().printStackTrace();
130 e.getChannel().close();
131 }
132
133 private static String getWebSocketLocation(HttpRequest req) {
134 return "ws://" + req.getHeader(HttpHeaders.Names.HOST);
135 }
136 }