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;
20 import io.netty.bootstrap.ServerBootstrap;
21 import io.netty.channel.Channel;
22 import io.netty.channel.EventLoopGroup;
23 import io.netty.channel.nio.NioEventLoopGroup;
24 import io.netty.channel.socket.nio.NioServerSocketChannel;
26 import java.net.InetSocketAddress;
27 import java.net.SocketAddress;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.Future;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * A HTTP server which serves Web Socket requests at:
37 * http://localhost:8080/websocket
39 * Open your browser at http://localhost:8080/, then the demo page will be loaded and a Web Socket connection will be
42 * This server illustrates support for the different web socket specification versions and will work with:
45 * <li>Safari 5+ (draft-ietf-hybi-thewebsocketprotocol-00)
46 * <li>Chrome 6-13 (draft-ietf-hybi-thewebsocketprotocol-00)
47 * <li>Chrome 14+ (draft-ietf-hybi-thewebsocketprotocol-10)
48 * <li>Chrome 16+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
49 * <li>Firefox 7+ (draft-ietf-hybi-thewebsocketprotocol-10)
50 * <li>Firefox 11+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
53 public class WebSocketServer implements Runnable {
56 * Utilized to get the port on which the server listens. This is a future as
57 * the port is selected dynamically from available ports, thus until the
58 * server is started the value will not be established.
60 private final SettableFuture<Integer> port;
63 * Maintains the port number with which the class was initialized.
65 private final int inPort;
66 private final ServerBootstrap bootstrap = new ServerBootstrap();
67 private final EventLoopGroup bossGroup = new NioEventLoopGroup();
68 private final EventLoopGroup workerGroup = new NioEventLoopGroup();
69 private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class.toString());
72 public WebSocketServer(final int inPort) {
74 port = SettableFuture.create();
81 } catch (Exception e) {
82 logger.info("Exception occured while starting webSocket server {}",e);
86 public Future<Integer> getPort() {
90 public void startServer() throws Exception {
92 bootstrap.group(bossGroup, workerGroup)
93 .channel(NioServerSocketChannel.class)
94 .childHandler(new WebSocketServerInitializer());
96 Channel ch = bootstrap.bind(inPort).sync().channel();
97 SocketAddress localSocket = ch.localAddress();
99 port.set(((InetSocketAddress) localSocket).getPort());
100 } catch (ClassCastException cce) {
101 throw new ExecutionException("Unknown socket address type", cce);
103 logger.info("Web socket server started at port " + port.get() + '.');
104 logger.info("Open your browser and navigate to http://localhost:" + port.get() + '/');
107 ch.closeFuture().sync();
108 } catch (InterruptedException ie) {
109 // No op, sometimes the server is shutdown hard
112 bossGroup.shutdownGracefully();
113 workerGroup.shutdownGracefully();