2 * Copyright 2012 The Netty Project
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
16 package org.opendaylight.yangtools.websocket.server;
18 import com.google.common.util.concurrent.SettableFuture;
19 import io.netty.bootstrap.ServerBootstrap;
20 import io.netty.channel.Channel;
21 import io.netty.channel.EventLoopGroup;
22 import io.netty.channel.nio.NioEventLoopGroup;
23 import io.netty.channel.socket.nio.NioServerSocketChannel;
24 import java.net.InetSocketAddress;
25 import java.net.SocketAddress;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.Future;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * A HTTP server which serves Web Socket requests at:
34 * http://localhost:8080/websocket
36 * Open your browser at http://localhost:8080/, then the demo page will be loaded and a Web Socket connection will be
39 * This server illustrates support for the different web socket specification versions and will work with:
42 * <li>Safari 5+ (draft-ietf-hybi-thewebsocketprotocol-00)
43 * <li>Chrome 6-13 (draft-ietf-hybi-thewebsocketprotocol-00)
44 * <li>Chrome 14+ (draft-ietf-hybi-thewebsocketprotocol-10)
45 * <li>Chrome 16+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
46 * <li>Firefox 7+ (draft-ietf-hybi-thewebsocketprotocol-10)
47 * <li>Firefox 11+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
51 public class WebSocketServer implements Runnable {
54 * Utilized to get the port on which the server listens. This is a future as
55 * the port is selected dynamically from available ports, thus until the
56 * server is started the value will not be established.
58 private final SettableFuture<Integer> port;
61 * Maintains the port number with which the class was initialized.
63 private final int inPort;
64 private final ServerBootstrap bootstrap = new ServerBootstrap();
65 private final EventLoopGroup bossGroup = new NioEventLoopGroup();
66 private final EventLoopGroup workerGroup = new NioEventLoopGroup();
67 private static final Logger LOG = LoggerFactory.getLogger(WebSocketServer.class);
70 public WebSocketServer(final int inPort) {
72 port = SettableFuture.create();
79 } catch (Exception e) {
80 LOG.info("Exception occured while starting webSocket server {}",e);
84 public Future<Integer> getPort() {
88 public void startServer() throws Exception {
90 bootstrap.group(bossGroup, workerGroup)
91 .channel(NioServerSocketChannel.class)
92 .childHandler(new WebSocketServerInitializer());
94 Channel ch = bootstrap.bind(inPort).sync().channel();
95 SocketAddress localSocket = ch.localAddress();
97 port.set(((InetSocketAddress) localSocket).getPort());
98 } catch (ClassCastException cce) {
99 throw new ExecutionException("Unknown socket address type", cce);
101 LOG.info("Web socket server started at port " + port.get() + '.');
102 LOG.info("Open your browser and navigate to http://localhost:" + port.get() + '/');
105 ch.closeFuture().sync();
106 } catch (InterruptedException ie) {
107 // No op, sometimes the server is shutdown hard
110 bossGroup.shutdownGracefully();
111 workerGroup.shutdownGracefully();