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