View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2012 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.core.io;
20  
21  import java.io.IOException;
22  import java.net.InetSocketAddress;
23  import java.nio.ByteBuffer;
24  
25  import org.eclipse.jetty.util.BufferUtil;
26  import org.eclipse.jetty.util.Callback;
27  import org.eclipse.jetty.util.log.Log;
28  import org.eclipse.jetty.util.log.Logger;
29  import org.eclipse.jetty.websocket.core.api.BaseConnection;
30  import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
31  import org.eclipse.jetty.websocket.core.api.WebSocketException;
32  import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
33  import org.eclipse.jetty.websocket.core.io.event.EventDriver;
34  import org.eclipse.jetty.websocket.core.protocol.OpCode;
35  import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
36  
37  public class WebSocketSession implements WebSocketConnection, IncomingFrames, OutgoingFrames
38  {
39      private static final Logger LOG = Log.getLogger(WebSocketSession.class);
40  
41      /**
42       * The reference to the base connection.
43       * <p>
44       * This will be the {@link AbstractWebSocketConnection} on normal websocket use, and be a MuxConnection when MUX is in the picture.
45       */
46      private final BaseConnection baseConnection;
47      private final WebSocketPolicy policy;
48      private final String subprotocol;
49      private final EventDriver websocket;
50      private OutgoingFrames outgoing;
51  
52      public WebSocketSession(EventDriver websocket, BaseConnection connection, WebSocketPolicy policy, String subprotocol)
53      {
54          super();
55          this.websocket = websocket;
56          this.baseConnection = connection;
57          this.policy = policy;
58          this.subprotocol = subprotocol;
59      }
60  
61      @Override
62      public void close()
63      {
64          baseConnection.close();
65      }
66  
67      @Override
68      public void close(int statusCode, String reason)
69      {
70          baseConnection.close(statusCode,reason);
71      }
72  
73      @Override
74      public void disconnect()
75      {
76          baseConnection.disconnect();
77      }
78  
79      public IncomingFrames getIncoming()
80      {
81          return websocket;
82      }
83  
84      public OutgoingFrames getOutgoing()
85      {
86          return outgoing;
87      }
88  
89      @Override
90      public WebSocketPolicy getPolicy()
91      {
92          return policy;
93      }
94  
95      @Override
96      public InetSocketAddress getRemoteAddress()
97      {
98          return baseConnection.getRemoteAddress();
99      }
100 
101     @Override
102     public BaseConnection.State getState()
103     {
104         return baseConnection.getState();
105     }
106 
107     @Override
108     public String getSubProtocol()
109     {
110         return subprotocol;
111     }
112 
113     @Override
114     public void incoming(WebSocketException e)
115     {
116         // pass on incoming to websocket itself
117         websocket.incoming(e);
118     }
119 
120     @Override
121     public void incoming(WebSocketFrame frame)
122     {
123         // pass on incoming to websocket itself
124         websocket.incoming(frame);
125     }
126 
127     @Override
128     public boolean isOpen()
129     {
130         return baseConnection.isOpen();
131     }
132 
133     @Override
134     public boolean isReading()
135     {
136         return baseConnection.isReading();
137     }
138 
139     @Override
140     public void notifyClosing()
141     {
142         baseConnection.notifyClosing();
143     }
144 
145     public void onConnect()
146     {
147         LOG.debug("onConnect()");
148         websocket.setSession(this);
149         websocket.onConnect();
150     }
151 
152     @Override
153     public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
154     {
155         if (LOG.isDebugEnabled())
156         {
157             LOG.debug("output({},{},{}) - {}",context,callback,frame,outgoing);
158         }
159         // forward on to chain
160         outgoing.output(context,callback,frame);
161     }
162 
163     /**
164      * {@inheritDoc}
165      */
166     @Override
167     public <C> void ping(C context, Callback<C> callback, byte[] payload) throws IOException
168     {
169         // Delegate the application called ping to the OutgoingFrames interface to allow
170         // extensions to process the frame appropriately.
171         WebSocketFrame frame = new WebSocketFrame(OpCode.PING).setPayload(payload);
172         frame.setFin(true);
173         output(context,callback,frame);
174     }
175 
176     public void setOutgoing(OutgoingFrames outgoing)
177     {
178         this.outgoing = outgoing;
179     }
180 
181     @Override
182     public SuspendToken suspend()
183     {
184         return baseConnection.suspend();
185     }
186 
187     @Override
188     public String toString()
189     {
190         StringBuilder builder = new StringBuilder();
191         builder.append("WebSocketSession[websocket=");
192         builder.append(websocket);
193         builder.append(",baseConnection=");
194         builder.append(baseConnection);
195         builder.append(",subprotocol=");
196         builder.append(subprotocol);
197         builder.append(",outgoing=");
198         builder.append(outgoing);
199         builder.append("]");
200         return builder.toString();
201     }
202 
203     /**
204      * {@inheritDoc}
205      */
206     @Override
207     public <C> void write(C context, Callback<C> callback, byte[] buf, int offset, int len) throws IOException
208     {
209         if (LOG.isDebugEnabled())
210         {
211             LOG.debug("write(context,{},byte[],{},{})",callback,offset,len);
212         }
213         // Delegate the application called write to the OutgoingFrames interface to allow
214         // extensions to process the frame appropriately.
215         WebSocketFrame frame = WebSocketFrame.binary().setPayload(buf,offset,len);
216         frame.setFin(true);
217         output(context,callback,frame);
218     }
219 
220     /**
221      * {@inheritDoc}
222      */
223     @Override
224     public <C> void write(C context, Callback<C> callback, ByteBuffer buffer) throws IOException
225     {
226         if (LOG.isDebugEnabled())
227         {
228             LOG.debug("write(context,{},ByteBuffer->{})",callback,BufferUtil.toDetailString(buffer));
229         }
230         // Delegate the application called write to the OutgoingFrames interface to allow
231         // extensions to process the frame appropriately.
232         WebSocketFrame frame = WebSocketFrame.binary().setPayload(buffer);
233         frame.setFin(true);
234         output(context,callback,frame);
235     }
236 
237     /**
238      * {@inheritDoc}
239      */
240     @Override
241     public <C> void write(C context, Callback<C> callback, String message) throws IOException
242     {
243         if (LOG.isDebugEnabled())
244         {
245             LOG.debug("write(context,{},message.length:{})",callback,message.length());
246         }
247         // Delegate the application called ping to the OutgoingFrames interface to allow
248         // extensions to process the frame appropriately.
249         WebSocketFrame frame = WebSocketFrame.text(message);
250         frame.setFin(true);
251         output(context,callback,frame);
252     }
253 }