View Javadoc

1   package org.eclipse.jetty.websocket;
2   
3   import java.io.IOException;
4   import java.util.concurrent.ConcurrentLinkedQueue;
5   
6   import javax.servlet.http.HttpServletRequest;
7   
8   import org.eclipse.jetty.server.Server;
9   import org.eclipse.jetty.server.handler.ResourceHandler;
10  import org.eclipse.jetty.server.nio.SelectChannelConnector;
11  import org.eclipse.jetty.util.StringUtil;
12  import org.eclipse.jetty.util.TypeUtil;
13  import org.eclipse.jetty.util.log.Log;
14  
15  public class TestServer extends Server
16  {
17      boolean _verbose;
18  
19      WebSocket _websocket;
20      SelectChannelConnector _connector;
21      WebSocketHandler _wsHandler;
22      ResourceHandler _rHandler;
23      ConcurrentLinkedQueue<TestWebSocket> _broadcast = new ConcurrentLinkedQueue<TestWebSocket>();
24  
25      public TestServer(int port)
26      {
27          _connector = new SelectChannelConnector();
28          _connector.setPort(port);
29  
30          addConnector(_connector);
31          _wsHandler = new WebSocketHandler()
32          {
33              public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
34              {
35                  if ("org.ietf.websocket.test-echo".equals(protocol) || "echo".equals(protocol) || "lws-mirror-protocol".equals(protocol))
36                  {
37                      _websocket = new TestEchoWebSocket();        
38                  }
39                  else if ("org.ietf.websocket.test-echo-broadcast".equals(protocol) || "echo-broadcast".equals(protocol))
40                  {
41                      _websocket = new TestEchoBroadcastWebSocket(); 
42  
43                  }
44                  else if ("org.ietf.websocket.test-echo-assemble".equals(protocol) || "echo-assemble".equals(protocol))
45                  {
46                      _websocket = new TestEchoAssembleWebSocket();
47                  }
48                  else if ("org.ietf.websocket.test-echo-fragment".equals(protocol) || "echo-fragment".equals(protocol))
49                  {
50                      _websocket = new TestEchoFragmentWebSocket();
51                  }
52                  else if (protocol==null)
53                  {
54                      _websocket = new TestWebSocket(); 
55                  }
56                  return _websocket;
57              }
58          };
59  
60          setHandler(_wsHandler);
61          
62          _rHandler=new ResourceHandler();
63          _rHandler.setDirectoriesListed(true);
64          _rHandler.setResourceBase("src/test/webapp");
65          _wsHandler.setHandler(_rHandler);
66     
67      }
68  
69      /* ------------------------------------------------------------ */
70      public boolean isVerbose()
71      {
72          return _verbose;
73      }
74  
75      /* ------------------------------------------------------------ */
76      public void setVerbose(boolean verbose)
77      {
78          _verbose = verbose;
79      }
80  
81      /* ------------------------------------------------------------ */
82      public void setResourceBase(String dir)
83      {
84          _rHandler.setResourceBase(dir);
85      }
86  
87      /* ------------------------------------------------------------ */
88      public String getResourceBase()
89      {
90          return _rHandler.getResourceBase();
91      }
92      
93      /* ------------------------------------------------------------ */
94      /* ------------------------------------------------------------ */
95      class TestWebSocket implements WebSocket, WebSocket.OnFrame, WebSocket.OnBinaryMessage, WebSocket.OnTextMessage, WebSocket.OnControl
96      {
97          protected FrameConnection _connection;
98          
99          public FrameConnection getConnection()
100         {
101             return _connection;
102         }
103         
104         public void onOpen(Connection connection)
105         {
106             if (_verbose)
107                 System.err.printf("%s#onOpen %s\n",this.getClass().getSimpleName(),connection);
108         }
109         
110         public void onHandshake(FrameConnection connection)
111         {
112             if (_verbose)
113                 System.err.printf("%s#onHandshake %s %s\n",this.getClass().getSimpleName(),connection,connection.getClass().getSimpleName());
114             _connection = connection;
115         }
116 
117         public void onClose(int code,String message)
118         {
119             if (_verbose)
120                 System.err.printf("%s#onDisonnect %d %s\n",this.getClass().getSimpleName(),code,message);
121         }
122         
123         public boolean onFrame(byte flags, byte opcode, byte[] data, int offset, int length)
124         {            
125             if (_verbose)
126                 System.err.printf("%s#onFrame %s|%s %s\n",this.getClass().getSimpleName(),TypeUtil.toHexString(flags),TypeUtil.toHexString(opcode),TypeUtil.toHexString(data,offset,length));
127             return false;
128         }
129 
130         public boolean onControl(byte controlCode, byte[] data, int offset, int length)
131         {
132             if (_verbose)
133                 System.err.printf("%s#onControl  %s %s\n",this.getClass().getSimpleName(),TypeUtil.toHexString(controlCode),TypeUtil.toHexString(data,offset,length));            
134             return false;
135         }
136 
137         public void onMessage(String data)
138         {
139             if (_verbose)
140                 System.err.printf("%s#onMessage     %s\n",this.getClass().getSimpleName(),data);
141         }
142 
143         public void onMessage(byte[] data, int offset, int length)
144         {
145             if (_verbose)
146                 System.err.printf("%s#onMessage     %s\n",this.getClass().getSimpleName(),TypeUtil.toHexString(data,offset,length));
147         }
148     }
149     
150     /* ------------------------------------------------------------ */
151     /* ------------------------------------------------------------ */
152     class TestEchoWebSocket extends TestWebSocket 
153     {
154         @Override
155         public void onOpen(Connection connection)
156         {
157             super.onOpen(connection);
158             connection.setMaxTextMessageSize(-1);
159             connection.setMaxBinaryMessageSize(-1);
160         }
161         
162         @Override
163         public boolean onFrame(byte flags, byte opcode, byte[] data, int offset, int length)
164         {
165             super.onFrame(flags,opcode,data,offset,length);
166             try
167             {
168                 if (!getConnection().isControl(opcode))
169                     getConnection().sendFrame(flags,opcode,data,offset,length);             }
170             catch (IOException e)
171             {
172                 e.printStackTrace();
173             }
174             
175             return false;
176         }
177     }
178     
179     /* ------------------------------------------------------------ */
180     /* ------------------------------------------------------------ */
181     class TestEchoBroadcastWebSocket extends TestWebSocket
182     {
183         @Override
184         public void onOpen(Connection connection)
185         {
186             super.onOpen(connection);
187             _broadcast.add(this);
188         }
189 
190         @Override
191         public void onClose(int code,String message)
192         {
193             super.onClose(code,message);
194             _broadcast.remove(this);
195         }
196         
197         @Override
198         public void onMessage(byte[] data, int offset, int length)
199         {
200             super.onMessage(data,offset,length);
201             for (TestWebSocket ws : _broadcast)
202             {
203                 try
204                 {
205                     ws.getConnection().sendMessage(data,offset,length); 
206                 }
207                 catch (IOException e)
208                 {
209                     _broadcast.remove(ws);
210                     e.printStackTrace();
211                 }
212             }
213         }
214 
215         @Override
216         public void onMessage(final String data)
217         {
218             super.onMessage(data);
219             for (TestWebSocket ws : _broadcast)
220             {
221                 try
222                 {
223                     ws.getConnection().sendMessage(data); 
224                 }
225                 catch (IOException e)
226                 {
227                     _broadcast.remove(ws);
228                     e.printStackTrace();
229                 }
230             }
231         }
232     }
233     
234     /* ------------------------------------------------------------ */
235     /* ------------------------------------------------------------ */
236     class TestEchoAssembleWebSocket extends TestWebSocket
237     {
238         
239         @Override
240         public void onOpen(Connection connection)
241         {
242             super.onOpen(connection);
243             connection.setMaxTextMessageSize(64*1024);
244             connection.setMaxBinaryMessageSize(64*1024);
245         }
246 
247         @Override
248         public void onMessage(byte[] data, int offset, int length)
249         {
250             super.onMessage(data,offset,length);
251             try
252             {
253                 getConnection().sendMessage(data,offset,length); 
254             }
255             catch (IOException e)
256             {
257                 e.printStackTrace();
258             }
259         }
260 
261         @Override
262         public void onMessage(final String data)
263         {
264             super.onMessage(data);
265             try
266             {
267                 getConnection().sendMessage(data); 
268             }
269             catch (IOException e)
270             {
271                 e.printStackTrace();
272             }
273         }
274     }
275     
276     /* ------------------------------------------------------------ */
277     /* ------------------------------------------------------------ */
278     class TestEchoFragmentWebSocket extends TestWebSocket
279     {
280         @Override
281         public void onOpen(Connection connection)
282         {
283             super.onOpen(connection);
284             connection.setMaxTextMessageSize(64*1024);
285             connection.setMaxBinaryMessageSize(64*1024);
286         }
287 
288         @Override
289         public void onMessage(byte[] data, int offset, int length)
290         {
291             super.onMessage(data,offset,length);
292             try
293             {
294                 getConnection().sendFrame((byte)0x0,getConnection().binaryOpcode(),data,offset,length/2); 
295                 getConnection().sendFrame((byte)0x8,getConnection().binaryOpcode(),data,offset+length/2,length-length/2); 
296             }
297             catch (IOException e)
298             {
299                 e.printStackTrace();
300             }
301         }
302 
303         @Override
304         public void onMessage(final String message)
305         {
306             super.onMessage(message);
307             try
308             {
309                 byte[] data = message.getBytes(StringUtil.__UTF8);
310                 int offset=0;
311                 int length=data.length;
312                 getConnection().sendFrame((byte)0x0,getConnection().textOpcode(),data,offset,length/2); 
313                 getConnection().sendFrame((byte)0x8,getConnection().textOpcode(),data,offset+length/2,length-length/2); 
314             }
315             catch (IOException e)
316             {
317                 e.printStackTrace();
318             }
319         }
320     }
321 
322     private static void usage()
323     {
324         System.err.println("java -cp CLASSPATH "+TestServer.class+" [ OPTIONS ]");
325         System.err.println("  -p|--port PORT    (default 8080)");
326         System.err.println("  -v|--verbose ");
327         System.err.println("  -d|--docroot file (default 'src/test/webapp')");
328         System.exit(1);
329     }
330     
331     public static void main(String... args)
332     {
333         try
334         {
335             int port=8080;
336             boolean verbose=false;
337             String docroot="src/test/webapp";
338             
339             for (int i=0;i<args.length;i++)
340             {
341                 String a=args[i];
342                 if ("-p".equals(a)||"--port".equals(a))
343                     port=Integer.parseInt(args[++i]);
344                 else if ("-v".equals(a)||"--verbose".equals(a))
345                     verbose=true;
346                 else if ("-d".equals(a)||"--docroot".equals(a))
347                     docroot=args[++i];
348                 else if (a.startsWith("-"))
349                     usage();
350             }
351             
352             
353             TestServer server = new TestServer(port);
354             server.setVerbose(verbose);
355             server.setResourceBase(docroot);
356             server.start();
357             server.join();
358         }
359         catch (Exception e)
360         {
361             Log.warn(e);
362         }
363     }
364 
365 
366 }