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 io.netty.bootstrap.ServerBootstrap;
19 import io.netty.channel.Channel;
20 import io.netty.channel.EventLoopGroup;
21 import io.netty.channel.nio.NioEventLoopGroup;
22 import io.netty.channel.socket.nio.NioServerSocketChannel;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 import java.net.SocketAddress;
28 import java.net.InetSocketAddress;
30 import java.util.concurrent.Future;
31 import java.util.concurrent.TimeUnit;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.TimeoutException;
35 import com.google.common.util.concurrent.SettableFuture;
38 * A HTTP server which serves Web Socket requests at:
40 * http://localhost:8080/websocket
42 * Open your browser at http://localhost:8080/, then the demo page will be loaded and a Web Socket connection will be
45 * This server illustrates support for the different web socket specification versions and will work with:
48 * <li>Safari 5+ (draft-ietf-hybi-thewebsocketprotocol-00)
49 * <li>Chrome 6-13 (draft-ietf-hybi-thewebsocketprotocol-00)
50 * <li>Chrome 14+ (draft-ietf-hybi-thewebsocketprotocol-10)
51 * <li>Chrome 16+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
52 * <li>Firefox 7+ (draft-ietf-hybi-thewebsocketprotocol-10)
53 * <li>Firefox 11+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
56 public class WebSocketServer implements Runnable {
59 * Utilized to get the port on which the server listens. This is a future as
60 * the port is selected dynamically from available ports, thus until the
61 * server is started the value will not be established.
63 private final SettableFuture<Integer> port;
66 * Maintains the port number with which the class was initialized.
68 private final int inPort;
69 private final ServerBootstrap bootstrap = new ServerBootstrap();
70 private final EventLoopGroup bossGroup = new NioEventLoopGroup();
71 private final EventLoopGroup workerGroup = new NioEventLoopGroup();
72 private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class.toString());
75 public WebSocketServer(int inPort) {
77 port = SettableFuture.<Integer>create();
83 } catch (Exception e) {
84 logger.info("Exception occured while starting webSocket server {}",e);
88 public Future<Integer> getPort() {
92 public void startServer() throws Exception {
94 bootstrap.group(bossGroup, workerGroup)
95 .channel(NioServerSocketChannel.class)
96 .childHandler(new WebSocketServerInitializer());
98 Channel ch = bootstrap.bind(inPort).sync().channel();
99 SocketAddress localSocket = ch.localAddress();
101 port.set(((InetSocketAddress) localSocket).getPort());
102 } catch (ClassCastException cce) {
103 throw new ExecutionException("Unknown socket address type", cce);
105 logger.info("Web socket server started at port " + port.get() + '.');
106 logger.info("Open your browser and navigate to http://localhost:" + port.get() + '/');
109 ch.closeFuture().sync();
110 } catch (InterruptedException ie) {
111 // No op, sometimes the server is shutdown hard
114 bossGroup.shutdownGracefully();
115 workerGroup.shutdownGracefully();