View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
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:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
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
14   * under the License.
15   */
16  //The MIT License
17  //
18  //Copyright (c) 2009 Carl Bystršm
19  //
20  //Permission is hereby granted, free of charge, to any person obtaining a copy
21  //of this software and associated documentation files (the "Software"), to deal
22  //in the Software without restriction, including without limitation the rights
23  //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24  //copies of the Software, and to permit persons to whom the Software is
25  //furnished to do so, subject to the following conditions:
26  //
27  //The above copyright notice and this permission notice shall be included in
28  //all copies or substantial portions of the Software.
29  //
30  //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31  //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32  //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33  //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34  //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35  //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36  //THE SOFTWARE.
37  
38  package io.netty5.example.http.websocketx.client;
39  
40  import io.netty5.channel.Channel;
41  import io.netty5.channel.ChannelHandlerContext;
42  import io.netty5.channel.SimpleChannelInboundHandler;
43  import io.netty5.handler.codec.http.FullHttpResponse;
44  import io.netty5.handler.codec.http.websocketx.CloseWebSocketFrame;
45  import io.netty5.handler.codec.http.websocketx.PongWebSocketFrame;
46  import io.netty5.handler.codec.http.websocketx.TextWebSocketFrame;
47  import io.netty5.handler.codec.http.websocketx.WebSocketClientHandshaker;
48  import io.netty5.handler.codec.http.websocketx.WebSocketFrame;
49  import io.netty5.handler.codec.http.websocketx.WebSocketHandshakeException;
50  import io.netty5.util.CharsetUtil;
51  import io.netty5.util.concurrent.Future;
52  import io.netty5.util.concurrent.Promise;
53  
54  public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {
55  
56      private final WebSocketClientHandshaker handshaker;
57      private Promise<Void> handshakeFuture;
58  
59      public WebSocketClientHandler(WebSocketClientHandshaker handshaker) {
60          this.handshaker = handshaker;
61      }
62  
63      public Future<Void> handshakeFuture() {
64          return handshakeFuture.asFuture();
65      }
66  
67      @Override
68      public void handlerAdded(ChannelHandlerContext ctx) {
69          handshakeFuture = ctx.newPromise();
70      }
71  
72      @Override
73      public void channelActive(ChannelHandlerContext ctx) {
74          handshaker.handshake(ctx.channel());
75      }
76  
77      @Override
78      public void channelInactive(ChannelHandlerContext ctx) {
79          System.out.println("WebSocket Client disconnected!");
80      }
81  
82      @Override
83      public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
84          Channel ch = ctx.channel();
85          if (!handshaker.isHandshakeComplete()) {
86              try {
87                  handshaker.finishHandshake(ch, (FullHttpResponse) msg);
88                  System.out.println("WebSocket Client connected!");
89                  handshakeFuture.setSuccess(null);
90              } catch (WebSocketHandshakeException e) {
91                  System.out.println("WebSocket Client failed to connect");
92                  handshakeFuture.setFailure(e);
93              }
94              return;
95          }
96  
97          if (msg instanceof FullHttpResponse) {
98              FullHttpResponse response = (FullHttpResponse) msg;
99              throw new IllegalStateException(
100                     "Unexpected FullHttpResponse (getStatus=" + response.status() +
101                             ", content=" + response.payload().toString(CharsetUtil.UTF_8) + ')');
102         }
103 
104         WebSocketFrame frame = (WebSocketFrame) msg;
105         if (frame instanceof TextWebSocketFrame) {
106             TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
107             System.out.println("WebSocket Client received message: " + textFrame.text());
108         } else if (frame instanceof PongWebSocketFrame) {
109             System.out.println("WebSocket Client received pong");
110         } else if (frame instanceof CloseWebSocketFrame) {
111             System.out.println("WebSocket Client received closing");
112             ch.close();
113         }
114     }
115 
116     @Override
117     public void channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
118         cause.printStackTrace();
119         if (!handshakeFuture.isDone()) {
120             handshakeFuture.setFailure(cause);
121         }
122         ctx.close();
123     }
124 }