View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.websocket.client.io;
20  
21  import java.net.InetSocketAddress;
22  import java.nio.ByteBuffer;
23  import java.util.concurrent.Executor;
24  import java.util.concurrent.atomic.AtomicBoolean;
25  
26  import org.eclipse.jetty.io.EndPoint;
27  import org.eclipse.jetty.util.log.Log;
28  import org.eclipse.jetty.util.log.Logger;
29  import org.eclipse.jetty.websocket.api.ProtocolException;
30  import org.eclipse.jetty.websocket.api.WriteCallback;
31  import org.eclipse.jetty.websocket.api.extensions.Frame;
32  import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
33  import org.eclipse.jetty.websocket.client.masks.Masker;
34  import org.eclipse.jetty.websocket.common.WebSocketFrame;
35  import org.eclipse.jetty.websocket.common.WebSocketSession;
36  import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
37  
38  /**
39   * Client side WebSocket physical connection.
40   */
41  public class WebSocketClientConnection extends AbstractWebSocketConnection
42  {
43      private static final Logger LOG = Log.getLogger(WebSocketClientConnection.class);
44      private final ConnectPromise connectPromise;
45      private final Masker masker;
46      private final AtomicBoolean opened = new AtomicBoolean(false);
47  
48      public WebSocketClientConnection(EndPoint endp, Executor executor, ConnectPromise connectPromise)
49      {
50          super(endp,executor,connectPromise.getClient().getScheduler(),connectPromise.getClient().getPolicy(),connectPromise.getClient().getBufferPool());
51          this.connectPromise = connectPromise;
52          this.masker = connectPromise.getMasker();
53          assert (this.masker != null);
54      }
55  
56      @Override
57      public InetSocketAddress getLocalAddress()
58      {
59          return getEndPoint().getLocalAddress();
60      }
61  
62      @Override
63      public InetSocketAddress getRemoteAddress()
64      {
65          return getEndPoint().getRemoteAddress();
66      }
67  
68      @Override
69      public void onClose()
70      {
71          super.onClose();
72          ConnectionManager connectionManager = connectPromise.getClient().getConnectionManager();
73          connectionManager.removeSession(getSession());
74      }
75  
76      @Override
77      public void onOpen()
78      {
79          boolean beenOpened = opened.getAndSet(true);
80          if (!beenOpened)
81          {
82              WebSocketSession session = getSession();
83              ConnectionManager connectionManager = connectPromise.getClient().getConnectionManager();
84              connectionManager.addSession(session);
85              connectPromise.succeeded(session);
86  
87              ByteBuffer extraBuf = connectPromise.getResponse().getRemainingBuffer();
88              if (extraBuf.hasRemaining())
89              {
90                  LOG.debug("Parsing extra remaining buffer from UpgradeConnection");
91                  getParser().parse(extraBuf);
92              }
93          }
94          super.onOpen();
95      }
96  
97      /**
98       * Overrride to set masker
99       */
100     @Override
101     public void outgoingFrame(Frame frame, WriteCallback callback)
102     {
103         if (frame instanceof WebSocketFrame)
104         {
105             if (masker == null)
106             {
107                 ProtocolException ex = new ProtocolException("Must set a Masker");
108                 LOG.warn(ex);
109                 if (callback != null)
110                 {
111                     callback.writeFailed(ex);
112                 }
113                 return;
114             }
115             masker.setMask((WebSocketFrame)frame);
116         }
117         super.outgoingFrame(frame,callback);
118     }
119 
120     @Override
121     public void setNextIncomingFrames(IncomingFrames incoming)
122     {
123         getParser().setIncomingFramesHandler(incoming);
124     }
125 }