From b1cd953d02e3929c9b86a408765272a6e2732f85 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Sun, 25 Nov 2012 10:22:44 +0100 Subject: [PATCH] Adding WebSocket Example using WebSocketServerProtocolHandler. --- .../html5/CustomTextFrameHandler.java | 30 ++++++ .../websocketx/html5/WebSocketServer.java | 98 +++++++++++++++++++ .../resources/websocketx/html5/css/socket.css | 4 + .../resources/websocketx/html5/js/socket.js | 50 ++++++++++ .../resources/websocketx/html5/websocket.html | 18 ++++ 5 files changed, 200 insertions(+) create mode 100644 example/src/main/java/io/netty/example/http/websocketx/html5/CustomTextFrameHandler.java create mode 100644 example/src/main/java/io/netty/example/http/websocketx/html5/WebSocketServer.java create mode 100644 example/src/main/resources/websocketx/html5/css/socket.css create mode 100644 example/src/main/resources/websocketx/html5/js/socket.js create mode 100644 example/src/main/resources/websocketx/html5/websocket.html diff --git a/example/src/main/java/io/netty/example/http/websocketx/html5/CustomTextFrameHandler.java b/example/src/main/java/io/netty/example/http/websocketx/html5/CustomTextFrameHandler.java new file mode 100644 index 0000000000..a9400767dd --- /dev/null +++ b/example/src/main/java/io/netty/example/http/websocketx/html5/CustomTextFrameHandler.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.example.http.websocketx.html5; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundMessageHandlerAdapter; +import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; + +public class CustomTextFrameHandler extends ChannelInboundMessageHandlerAdapter { + + @Override + public void messageReceived(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception { + String request = frame.getText(); + ctx.channel().write(new TextWebSocketFrame(request.toUpperCase())); + } + +} diff --git a/example/src/main/java/io/netty/example/http/websocketx/html5/WebSocketServer.java b/example/src/main/java/io/netty/example/http/websocketx/html5/WebSocketServer.java new file mode 100644 index 0000000000..b1b57a86ea --- /dev/null +++ b/example/src/main/java/io/netty/example/http/websocketx/html5/WebSocketServer.java @@ -0,0 +1,98 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, version + * 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.netty.example.http.websocketx.html5; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpChunkAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; + +import java.net.InetSocketAddress; + +/** + * A WebSocket Server that respondes to requests at: + * + *
+ * http://localhost:8080/websocket
+ * 
+ * + * The example differs from many of the other examples in Netty in that is does + * not have an acomponying client. Instead a html page is provided that + * interacts with this server.
+ * Open up the following file a web browser that supports WebSocket's: + * + *
+ * example/src/main/resources/websocketx/html5/websocket.html
+ * 
+ * + * The html page is very simple were you simply enter some text and the server + * will echo the same text back, but in uppercase. You, also see status messages + * in the "Response From Server" area when client has connected, disconnected + * etc. + * + */ +public class WebSocketServer { + + private final int port; + + public WebSocketServer(int port) { + this.port = port; + } + + public void run() throws Exception { + final ServerBootstrap sb = new ServerBootstrap(); + try { + sb.group(new NioEventLoopGroup(), new NioEventLoopGroup()) + .channel(NioServerSocketChannel.class) + .localAddress(new InetSocketAddress(port)) + .childHandler(new ChannelInitializer() { + @Override + public void initChannel(final SocketChannel ch) throws Exception { + ch.pipeline().addLast( + new HttpRequestDecoder(), + new HttpChunkAggregator(65536), + new HttpResponseEncoder(), + new WebSocketServerProtocolHandler("/websocket"), + new CustomTextFrameHandler()); + } + }); + + final Channel ch = sb.bind().sync().channel(); + System.out.println("Web socket server started at port " + port); + + ch.closeFuture().sync(); + } finally { + sb.shutdown(); + } + } + + public static void main(String[] args) throws Exception { + int port; + if (args.length > 0) { + port = Integer.parseInt(args[0]); + } else { + port = 8080; + } + new WebSocketServer(port).run(); + } + +} diff --git a/example/src/main/resources/websocketx/html5/css/socket.css b/example/src/main/resources/websocketx/html5/css/socket.css new file mode 100644 index 0000000000..c50fdef00e --- /dev/null +++ b/example/src/main/resources/websocketx/html5/css/socket.css @@ -0,0 +1,4 @@ +textarea { + width: 500px; + height: 300px; +} \ No newline at end of file diff --git a/example/src/main/resources/websocketx/html5/js/socket.js b/example/src/main/resources/websocketx/html5/js/socket.js new file mode 100644 index 0000000000..81994f18bd --- /dev/null +++ b/example/src/main/resources/websocketx/html5/js/socket.js @@ -0,0 +1,50 @@ +(function() { + var Sock = function() { + var socket; + if (!window.WebSocket) { + window.WebSocket = window.MozWebSocket; + } + + if (window.WebSocket) { + socket = new WebSocket("ws://localhost:8080/websocket"); + socket.onopen = onopen; + socket.onmessage = onmessage; + socket.onclose = onclose; + } else { + alert("Your browser does not support Web Socket."); + } + + function onopen(event) { + getTextAreaElement().value = "Web Socket opened!"; + } + + function onmessage(event) { + appendTextArea(event.data); + } + function onclose(event) { + appendTextArea("Web Socket closed"); + } + + function appendTextArea(newData) { + var el = getTextAreaElement(); + el.value = el.value + '\n' + newData; + } + + function getTextAreaElement() { + return document.getElementById('responseText'); + } + + function send(e) { + e.preventDefault(); + if (window.WebSocket) { + if (socket.readyState == WebSocket.OPEN) { + socket.send(event.target.message.value); + } else { + alert("The socket is not open."); + } + } + } + document.forms.inputform.addEventListener('submit', send, false); + } + window.addEventListener('load', function() { new Sock(); }, false); +})(); diff --git a/example/src/main/resources/websocketx/html5/websocket.html b/example/src/main/resources/websocketx/html5/websocket.html new file mode 100644 index 0000000000..f80d25a22c --- /dev/null +++ b/example/src/main/resources/websocketx/html5/websocket.html @@ -0,0 +1,18 @@ + + + + + Web Socket Example + + + + +

Enter a message

+
+ + +
+

Repsonse from Server

+ + +