Skip to content

Commit 41f1055

Browse files
committed
Merge remote-tracking branch 'upstream/master'
Resolved conflicts: src/org/java_websocket/WebSocket.java src/org/java_websocket/WebSocketClient.java
2 parents 8e32fc1 + 9e6882d commit 41f1055

25 files changed

Lines changed: 232 additions & 99 deletions

README.markdown

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ Java chat client (a `WebSocketClient` subclass):
3838
java -cp build/examples:dist/WebSocket.jar ChatClient
3939
```
4040

41+
__Note:__ If you're on Windows, then replace the `:` (colon) in the classpath
42+
in the commands above with a `;` (semicolon).
43+
4144
The chat client is a simple Swing GUI application that allows you to send
4245
messages to all other connected clients, and receive messages from others in a
4346
text box.
@@ -73,7 +76,7 @@ Minimum Required JDK
7376

7477
`Java-WebSocket` is known to work with:
7578

76-
* Java 1.4 (aka SE 6)
79+
* Java 1.5 (aka SE 6)
7780
* Android 1.6 (API 4)
7881

7982
Other JRE implementations may work as well, but haven't been tested.

example/AutobahnClientTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import java.io.IOException;
33
import java.io.InputStreamReader;
44
import java.net.URI;
5+
import java.nio.ByteBuffer;
56

67
import org.java_websocket.WebSocket;
78
import org.java_websocket.WebSocketClient;
@@ -135,7 +136,7 @@ public void onMessage( String message ) {
135136
}
136137

137138
@Override
138-
public void onMessage( byte[] blob ) {
139+
public void onMessage( ByteBuffer blob ) {
139140
try {
140141
getConnection().send( blob );
141142
} catch ( InterruptedException e ) {

example/AutobahnServerTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import java.net.InetSocketAddress;
22
import java.net.UnknownHostException;
3+
import java.nio.ByteBuffer;
34

45
import org.java_websocket.WebSocket;
56
import org.java_websocket.WebSocketServer;
@@ -44,7 +45,7 @@ public void onMessage( WebSocket conn, String message ) {
4445
}
4546

4647
@Override
47-
public void onMessage( WebSocket conn, byte[] blob ) {
48+
public void onMessage( WebSocket conn, ByteBuffer blob ) {
4849
try {
4950
conn.send( blob );
5051
} catch ( InterruptedException e ) {

example/ChatServer.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.net.InetAddress;
55
import java.net.InetSocketAddress;
66
import java.net.UnknownHostException;
7+
import java.util.Set;
78

89
import org.java_websocket.WebSocket;
910
import org.java_websocket.WebSocketServer;
@@ -17,15 +18,15 @@ public class ChatServer extends WebSocketServer {
1718
public ChatServer( int port ) throws UnknownHostException {
1819
super( new InetSocketAddress( InetAddress.getByName( "localhost" ), port ) );
1920
}
20-
21+
2122
public ChatServer( InetSocketAddress address ) {
2223
super( address );
2324
}
2425

2526
@Override
2627
public void onOpen( WebSocket conn, ClientHandshake handshake ) {
2728
try {
28-
this.sendToAll( conn + " entered the room!" );
29+
this.sendToAll( "new" );
2930
} catch ( InterruptedException ex ) {
3031
ex.printStackTrace();
3132
}
@@ -45,7 +46,7 @@ public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
4546
@Override
4647
public void onMessage( WebSocket conn, String message ) {
4748
try {
48-
this.sendToAll( conn + ": " + message );
49+
this.sendToAll( message );
4950
} catch ( InterruptedException ex ) {
5051
ex.printStackTrace();
5152
}
@@ -84,8 +85,11 @@ public void onError( WebSocket conn, Exception ex ) {
8485
* When socket related I/O errors occur.
8586
*/
8687
public void sendToAll( String text ) throws InterruptedException {
87-
for( WebSocket c : connections() ) {
88-
c.send( text );
88+
Set<WebSocket> con = connections();
89+
synchronized ( con ) {
90+
for( WebSocket c : con ) {
91+
c.send( text );
92+
}
8993
}
9094
}
9195
}

src/org/java_websocket/WebSocket.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.List;
1212
import java.util.concurrent.BlockingQueue;
1313
import java.util.concurrent.LinkedBlockingQueue;
14+
import java.util.concurrent.atomic.AtomicLong;
1415

1516
import org.java_websocket.drafts.Draft;
1617
import org.java_websocket.drafts.Draft.CloseHandshakeType;
@@ -57,6 +58,8 @@ public enum Role {
5758
public static final int READY_STATE_CLOSING = 2;
5859
public static final int READY_STATE_CLOSED = 3;
5960

61+
public static int BUFFERSIZE = 512;
62+
6063
/**
6164
* The default port of WebSockets, as defined in the spec. If the nullary
6265
* constructor is used, DEFAULT_PORT will be the port the WebSocketServer
@@ -92,11 +95,12 @@ public enum Role {
9295
* Queue of buffers that need to be sent to the client.
9396
*/
9497
private BlockingQueue<ByteBuffer> bufferQueue;
98+
9599
/**
96100
* The amount of bytes still in queue to be sent, at every given time.
97101
* It's updated at every send/sent operation.
98102
*/
99-
private Long bufferQueueTotalAmount = (long) 0;
103+
private AtomicLong bufferQueueTotalAmount = new AtomicLong( 0l );
100104

101105
private Draft draft = null;
102106

@@ -143,7 +147,7 @@ public WebSocket( WebSocketListener listener , List<Draft> drafts , SocketChanne
143147
private void init( WebSocketListener listener, Draft draft, SocketChannel socketchannel ) {
144148
this.sockchannel = socketchannel;
145149
this.bufferQueue = new LinkedBlockingQueue<ByteBuffer>( 3 );
146-
this.socketBuffer = ByteBuffer.allocate( 65558 );
150+
this.socketBuffer = ByteBuffer.allocate( BUFFERSIZE );
147151
socketBuffer.flip();
148152
this.wsl = listener;
149153
this.role = Role.CLIENT;
@@ -485,7 +489,7 @@ public void close( InvalidDataException e ) {
485489
* @throws InterruptedException
486490
* @throws NotYetConnectedException
487491
*/
488-
public void send( String text ) throws IllegalArgumentException , NotYetConnectedException , InterruptedException {
492+
public void send( String text ) throws NotYetConnectedException , InterruptedException {
489493
if( text == null )
490494
throw new IllegalArgumentException( "Cannot send 'null' data to a WebSocket." );
491495
send( draft.createFrames( text, role == Role.CLIENT ) );
@@ -498,12 +502,16 @@ public void send( String text ) throws IllegalArgumentException , NotYetConnecte
498502
* @throws InterruptedException
499503
* @throws NotYetConnectedException
500504
*/
501-
public void send( byte[] bytes ) throws IllegalArgumentException , NotYetConnectedException , InterruptedException {
505+
public void send( ByteBuffer bytes ) throws IllegalArgumentException , NotYetConnectedException , InterruptedException {
502506
if( bytes == null )
503507
throw new IllegalArgumentException( "Cannot send 'null' data to a WebSocket." );
504508
send( draft.createFrames( bytes, role == Role.CLIENT ) );
505509
}
506510

511+
public void send( byte[] bytes ) throws IllegalArgumentException , NotYetConnectedException , InterruptedException {
512+
send( ByteBuffer.wrap( bytes ) );
513+
}
514+
507515
private void send( Collection<Framedata> frames ) throws InterruptedException {
508516
if( !this.handshakeComplete )
509517
throw new NotYetConnectedException();
@@ -534,7 +542,7 @@ boolean hasBufferedData() {
534542
* @return Amount of Data still in Queue and not sent yet of the socket
535543
*/
536544
long bufferedDataAmount() {
537-
return bufferQueueTotalAmount;
545+
return bufferQueueTotalAmount.get();
538546
}
539547

540548
/**
@@ -545,16 +553,13 @@ public void flush() throws IOException {
545553
ByteBuffer buffer = this.bufferQueue.peek();
546554

547555
while ( buffer != null ) {
548-
sockchannel.write( buffer );
556+
int written = sockchannel.write( buffer );
549557
if( buffer.remaining() > 0 ) {
550558
// there is still stuff to send for this buffer
551559
continue;
552560
} else {
553-
// nothing left for this buffer
554-
synchronized ( bufferQueueTotalAmount ) {
555-
// subtract this amount of data from the total queued (synchronized over this object)
556-
bufferQueueTotalAmount -= buffer.limit();
557-
}
561+
// subtract this amount of data from the total queued (synchronized over this object)
562+
bufferQueueTotalAmount.addAndGet( -written );
558563

559564
// timing callback
560565
if ( isConnecting() ) {
@@ -608,13 +613,11 @@ public void startHandshake( ClientHandshakeBuilder handshakedata ) throws Invali
608613

609614
private void channelWrite( ByteBuffer buf ) throws InterruptedException {
610615
if( DEBUG )
611-
System.out.println( "write(" + buf.limit() + "): {" + ( buf.limit() > 1000 ? "too big to display" : new String( buf.array() ) ) + "}" );
616+
System.out.println( "write(" + buf.remaining() + "): {" + ( buf.remaining() > 1000 ? "too big to display" : new String( buf.array() ) ) + "}" );
617+
618+
// add up the number of bytes to the total queued (synchronized over this object)
619+
bufferQueueTotalAmount.addAndGet( buf.remaining() );
612620

613-
buf.rewind(); // TODO rewinding should not be nessesary
614-
synchronized ( bufferQueueTotalAmount ) {
615-
// add up the number of bytes to the total queued (synchronized over this object)
616-
bufferQueueTotalAmount += buf.limit();
617-
}
618621
if( !bufferQueue.offer( buf ) ) {
619622
try {
620623
flush();

src/org/java_websocket/WebSocketAdapter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.java_websocket;
22

3+
import java.nio.ByteBuffer;
4+
35
import org.java_websocket.drafts.Draft;
46
import org.java_websocket.exeptions.InvalidDataException;
57
import org.java_websocket.framing.Framedata;
@@ -76,7 +78,7 @@ public void onWebsocketClose( WebSocket conn, int code, String reason, boolean r
7678
* @see org.java_websocket.WebSocketListener#onWebsocketMessage(WebSocket, byte[])
7779
*/
7880
@Override
79-
public void onWebsocketMessage( WebSocket conn, byte[] blob ) {
81+
public void onWebsocketMessage( WebSocket conn, ByteBuffer blob ) {
8082
}
8183

8284
/**

src/org/java_websocket/WebSocketClient.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.IOException;
44
import java.net.InetSocketAddress;
55
import java.net.URI;
6+
import java.nio.ByteBuffer;
67
import java.nio.channels.ClosedByInterruptException;
78
import java.nio.channels.NotYetConnectedException;
89
import java.nio.channels.SelectionKey;
@@ -108,9 +109,12 @@ public void close() {
108109
if( thread != null ) {
109110
thread.interrupt();
110111
closelock.lock();
111-
if( selector != null )
112-
selector.wakeup();
113-
closelock.unlock();
112+
try {
113+
if( selector != null )
114+
selector.wakeup();
115+
} finally {
116+
closelock.unlock();
117+
}
114118
}
115119
}
116120

@@ -318,7 +322,7 @@ public final void onWebsocketMessage( WebSocket conn, String message ) {
318322
}
319323

320324
@Override
321-
public final void onWebsocketMessage( WebSocket conn, byte[] blob ) {
325+
public final void onWebsocketMessage( WebSocket conn, ByteBuffer blob ) {
322326
onMessage( blob );
323327
}
324328

@@ -367,7 +371,6 @@ public WebSocket getConnection() {
367371
public abstract void onMessage( String message );
368372
public abstract void onClose( int code, String reason, boolean remote );
369373
public abstract void onError( Exception ex );
370-
public void onMessage( byte[] bytes ) {
371-
}
372-
374+
public void onMessage( ByteBuffer bytes ) {
375+
};
373376
}

src/org/java_websocket/WebSocketListener.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.java_websocket;
22

3+
import java.nio.ByteBuffer;
4+
35
import org.java_websocket.drafts.Draft;
46
import org.java_websocket.exeptions.InvalidDataException;
57
import org.java_websocket.framing.Framedata;
@@ -83,7 +85,7 @@ enum MessageType { HANDSHAKE, CLOSE, TEXT, BINARY }
8385
* @param blob
8486
* The binary message that was received.
8587
*/
86-
public void onWebsocketMessage( WebSocket conn, byte[] blob );
88+
public void onWebsocketMessage( WebSocket conn, ByteBuffer blob );
8789

8890
/**
8991
* Called after <var>onHandshakeReceived</var> returns <var>true</var>.

src/org/java_websocket/WebSocketServer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.net.InetAddress;
55
import java.net.InetSocketAddress;
66
import java.net.UnknownHostException;
7+
import java.nio.ByteBuffer;
78
import java.nio.channels.SelectionKey;
89
import java.nio.channels.Selector;
910
import java.nio.channels.ServerSocketChannel;
@@ -258,7 +259,7 @@ public final void onWebsocketMessage( WebSocket conn, String message ) {
258259
}
259260

260261
@Override
261-
public final void onWebsocketMessage( WebSocket conn, byte[] blob ) {
262+
public final void onWebsocketMessage( WebSocket conn, ByteBuffer blob ) {
262263
onMessage( conn, blob );
263264
}
264265

@@ -299,7 +300,7 @@ public final void onWriteDemand( WebSocket conn ) {
299300
public abstract void onClose( WebSocket conn, int code, String reason, boolean remote );
300301
public abstract void onMessage( WebSocket conn, String message );
301302
public abstract void onError( WebSocket conn, Exception ex );
302-
public void onMessage( WebSocket conn, byte[] message ) {
303+
public void onMessage( WebSocket conn, ByteBuffer message ) {
303304
};
304305

305306
}

src/org/java_websocket/drafts/Draft.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public enum CloseHandshakeType {
4040
NONE, ONEWAY, TWOWAY
4141
}
4242

43+
public static int MAX_FAME_SIZE = 1000 * 1;
44+
public static int INITIAL_FAMESIZE = 64;
45+
4346
public static final byte[] FLASH_POLICY_REQUEST = Charsetfunctions.utf8Bytes( "<policy-file-request/>\0" );
4447
private static Pattern getpattern = Pattern.compile( "" ); // GET / HTTP/1.1
4548
private static Pattern statuspattern = Pattern.compile( "" ); // HTTP/1.1 101 Switching Protocols
@@ -118,7 +121,7 @@ protected boolean basicAccept( Handshakedata handshakedata ) {
118121

119122
public abstract ByteBuffer createBinaryFrame( Framedata framedata ); // TODO Allow to send data on the base of an Iterator or InputStream
120123

121-
public abstract List<Framedata> createFrames( byte[] binary, boolean mask );
124+
public abstract List<Framedata> createFrames( ByteBuffer binary, boolean mask );
122125

123126
public abstract List<Framedata> createFrames( String text, boolean mask );
124127

@@ -167,6 +170,8 @@ public List<ByteBuffer> createHandshake( Handshakedata handshakedata, Role ownro
167170

168171
public abstract List<Framedata> translateFrame( ByteBuffer buffer ) throws InvalidDataException;
169172

173+
public abstract CloseHandshakeType getCloseHandshakeType();
174+
170175
public Handshakedata translateHandshake( ByteBuffer buf ) throws InvalidHandshakeException {
171176
return translateHandshakeHttp( buf, role );
172177
}
@@ -181,6 +186,4 @@ public void setParseMode( Role role ) {
181186
this.role = role;
182187
}
183188

184-
public abstract CloseHandshakeType getCloseHandshakeType();
185-
186189
}

0 commit comments

Comments
 (0)