BUG-869: remove empty statements
[yangtools.git] / websocket / websocket-client / src / main / java / org / opendaylight / yangtools / websocket / client / WebSocketIClient.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.websocket.client;
9
10 import io.netty.bootstrap.Bootstrap;
11 import io.netty.buffer.Unpooled;
12 import io.netty.channel.Channel;
13 import io.netty.channel.ChannelInitializer;
14 import io.netty.channel.ChannelPipeline;
15 import io.netty.channel.EventLoop;
16 import io.netty.channel.EventLoopGroup;
17 import io.netty.channel.nio.NioEventLoopGroup;
18 import io.netty.channel.socket.SocketChannel;
19 import io.netty.channel.socket.nio.NioSocketChannel;
20 import io.netty.handler.codec.http.HttpClientCodec;
21 import io.netty.handler.codec.http.HttpObjectAggregator;
22 import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
23 import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
24 import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
25 import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
26 import io.netty.handler.codec.http.websocketx.WebSocketVersion;
27
28 import java.net.URI;
29
30 import org.opendaylight.yangtools.websocket.client.callback.ClientMessageCallback;
31
32 import com.google.common.base.Preconditions;
33
34 /**
35  * Implementation of web socket client that supports WS and HTTP protocols.
36  */
37 public class WebSocketIClient {
38     private final EventLoopGroup group = new NioEventLoopGroup();
39     private final Bootstrap bootstrap = new Bootstrap();
40     private final WebSocketClientHandler clientHandler;
41     private final URI uri;
42     private Channel clientChannel;
43
44     /**
45      * Creates new web socket client
46      *
47      * @param uri
48      *            URI
49      * @param clientMessageCallback
50      *            ClientMessageCallback
51      */
52     public WebSocketIClient(final URI uri, final ClientMessageCallback clientMessageCallback) {
53         this.uri = Preconditions.checkNotNull(uri);
54         clientHandler = new WebSocketClientHandler(
55                 WebSocketClientHandshakerFactory.newHandshaker(uri,
56                         WebSocketVersion.V13, null, false, null),
57                 clientMessageCallback); // last null could be replaced with
58                                         // DefaultHttpHeaders
59         initialize();
60     }
61
62     /**
63      * Initializes {@link Channel} one when it was registered to its
64      * {@link EventLoop}.
65      */
66     private void initialize() {
67
68         String protocol = uri.getScheme();
69         if (!"ws".equals(protocol) && !"http".equals(protocol)) {
70             throw new IllegalArgumentException("Unsupported protocol: "
71                     + protocol);
72         }
73
74         bootstrap.group(group).channel(NioSocketChannel.class)
75                 .handler(new ChannelInitializer<SocketChannel>() {
76                     @Override
77                     public void initChannel(final SocketChannel ch) {
78                         ChannelPipeline pipeline = ch.pipeline();
79                         pipeline.addLast("http-codec", new HttpClientCodec());
80                         pipeline.addLast("aggregator",
81                                 new HttpObjectAggregator(8192));
82                         pipeline.addLast("ws-handler", clientHandler);
83                     }
84                 });
85     }
86
87     /**
88      * Makes the connection attempt and notifies when the handshake process
89      * succeeds or fail.
90      */
91     public void connect() throws InterruptedException {
92         clientChannel = bootstrap.connect(uri.getHost(), uri.getPort()).sync()
93                 .channel();
94         clientHandler.handshakeFuture().sync();
95     }
96
97     /**
98      * Writes a String message through the
99      * {@link ChannelPipeline} and request to actual {@link Channel#flush()} to flush
100      * all pending data to the actual transport.
101      *
102      * @param message
103      *            a message to write
104      */
105     public void writeAndFlush(final String message) {
106         clientChannel.writeAndFlush(new TextWebSocketFrame(message));
107     }
108
109     /**
110      * Writes a Object message through the
111      * {@link ChannelPipeline} and request to actual {@link Channel#flush()} to flush
112      * all pending data to the actual transport.
113      *
114      * @param message
115      *            a message to write
116      */
117     public void writeAndFlush(final Object message) {
118         clientChannel.writeAndFlush(message);
119     }
120
121     /**
122      * Writes {@link PingWebSocketFrame}
123      * through the {@link ChannelPipeline} and request to actual
124      * {@link Channel#flush()} to flush all pending data to the actual transport.
125      */
126     public void ping() {
127         clientChannel.writeAndFlush(new PingWebSocketFrame(Unpooled
128                 .copiedBuffer(new byte[] { 1, 2, 3, 4, 5, 6 })));
129     }
130
131     /**
132      * Closes the connection when the server responds to the
133      * {@link CloseWebSocketFrame}.
134      */
135     public void close() throws InterruptedException {
136         clientChannel.writeAndFlush(new CloseWebSocketFrame());
137         clientChannel.closeFuture().sync();
138         group.shutdownGracefully();
139     }
140
141 }