diff --git a/jetty-websocket/README.txt b/jetty-websocket/README.txt index a17d4ff6c3b..07842211566 100644 --- a/jetty-websocket/README.txt +++ b/jetty-websocket/README.txt @@ -25,12 +25,15 @@ Without a protocol specified, the client will just send/receive websocket PING/P aspects of websocket. Specifically the server and client understand the following protocols: org.ietf.websocket.test-echo - Websocket TEXT messages are sent by the client and the server will echo every frame. + Websocket messages are sent by the client and the server will echo every frame. + + org.ietf.websocket.test-echo-broadcast + Websocket messages are sent by the client and the server will echo every frame to every connection. org.ietf.websocket.test-echo-assemble - Websocket BINARY messages are sent (see --fragment) and the server will echo assembled messages as a single frame. + Websocket messages are sent by the client and the server will echo assembled messages as a single frame. org.ietf.websocket.test-echo-fragment - Websocket BINARY messages are sent and the server will echo each message fragmented into 2 frames. + Websocket messages are sent and the server will echo each message fragmented into 2 frames. diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java index 46eb7e5417e..8a9efadc20c 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/TestClient.java @@ -35,21 +35,25 @@ public class TestClient private final SocketEndPoint _endp; private final WebSocketGeneratorD06 _generator; private final WebSocketParserD06 _parser; - private int _sent; - private int _received; + private int _framesSent; + private int _messagesSent; + private int _framesReceived; + private int _messagesReceived; private long _totalTime; private long _minDuration=Long.MAX_VALUE; private long _maxDuration=Long.MIN_VALUE; private long _start; private BlockingQueue _starts = new LinkedBlockingQueue(); - private BlockingQueue _pending = new LinkedBlockingQueue(); - + int _messageBytes; + int _frames; private final WebSocketParser.FrameHandler _handler = new WebSocketParser.FrameHandler() { public synchronized void onFrame(byte flags, byte opcode, Buffer buffer) { try { + _framesReceived++; + _frames++; if (opcode == WebSocketConnectionD06.OP_CLOSE) { byte[] data=buffer.asArray(); @@ -61,25 +65,24 @@ public class TestClient return; } - Long start=_starts.take(); - String data=_pending.take(); - - while (!data.equals(TypeUtil.toHexString(buffer.asArray())) && !_starts.isEmpty() && !_pending.isEmpty()) + _messageBytes+=buffer.length(); + + if (WebSocketConnectionD06.isLastFrame(flags)) { - // Missed response - start=_starts.take(); - data=_pending.take(); + _messagesReceived++; + Long start=_starts.take(); + + + long duration = System.nanoTime()-start.longValue(); + if (duration>_maxDuration) + _maxDuration=duration; + if (duration<_minDuration) + _minDuration=duration; + _totalTime+=duration; + System.out.printf("%d bytes from %s: frames=%d req=%d time=%.1fms opcode=0x%s\n",_messageBytes,_host,_frames,_messagesReceived,((double)duration/1000000.0),TypeUtil.toHexString(opcode)); + _frames=0; + _messageBytes=0; } - - _received++; - - long duration = System.nanoTime()-start.longValue(); - if (duration>_maxDuration) - _maxDuration=duration; - if (duration<_minDuration) - _minDuration=duration; - _totalTime+=duration; - System.out.printf("%d bytes from %s: req=%d time=%.1fms opcode=0x%s\n",buffer.length(),_host,_received,((double)duration/1000000.0),TypeUtil.toHexString(opcode)); } catch(Exception e) { @@ -183,23 +186,36 @@ public class TestClient break; try { - byte data[] = new byte[_size]; - __random.nextBytes(data); + byte data[]=null; + if (opcode==WebSocketConnectionD06.OP_TEXT) + { + StringBuilder b = new StringBuilder(); + while (b.length()<_size) + b.append('A'+__random.nextInt(26)); + data=b.toString().getBytes(StringUtil.__UTF8); + } + else + { + data= new byte[_size]; + __random.nextBytes(data); + } _starts.add(System.nanoTime()); - _pending.add(TypeUtil.toHexString(data)); int off=0; int len=data.length; if (fragment>0&& len>fragment) len=fragment; + _messagesSent++; while(offlen) len=data.length-off; + if (fragment>0&& len>fragment) + len=fragment; } _generator.flush(_socket.getSoTimeout()); @@ -219,10 +235,10 @@ public class TestClient _socket.close(); long duration=System.currentTimeMillis()-_start; System.out.println("--- "+_host+" websocket ping statistics using 1 connection ---"); - System.out.println(_sent+" packets transmitted, "+_received+" received, "+ - (_sent>0?String.format("%d",100*(_sent-_received)/_sent)+"% loss, ":"")+ + System.out.println(_framesSent+" frames transmitted, "+_framesReceived+" received, "+ + _messagesSent+" messages transmitted, "+_messagesReceived+" received, "+ "time "+duration+"ms"); - System.out.printf("rtt min/ave/max = %.3f/%.3f/%.3f ms\n",_minDuration/1000000.0,_received==0?0.0:(_totalTime/_received/1000000.0),_maxDuration/1000000.0); + System.out.printf("rtt min/ave/max = %.3f/%.3f/%.3f ms\n",_minDuration/1000000.0,_messagesReceived==0?0.0:(_totalTime/_messagesReceived/1000000.0),_maxDuration/1000000.0); } @@ -232,11 +248,12 @@ public class TestClient System.err.println("USAGE: java -cp CLASSPATH "+TestClient.class+" [ OPTIONS ]"); System.err.println(" -h|--host HOST (default localhost)"); System.err.println(" -p|--port PORT (default 8080)"); + System.err.println(" -b|--binary"); System.err.println(" -v|--verbose"); System.err.println(" -c|--count n (default 10)"); System.err.println(" -s|--size n (default 64)"); System.err.println(" -f|--fragment n (default 4000) "); - System.err.println(" -P|--protocol echo|echo-assemble|echo-fragment"); + System.err.println(" -P|--protocol echo|echo-assemble|echo-fragment|echo-broadcast"); System.exit(1); } @@ -251,6 +268,7 @@ public class TestClient int count=10; int size=64; int fragment=4000; + boolean binary=false; for (int i=0;i