Skip to content

Commit c9b4dbc

Browse files
committed
Merge pull request TooTallNate#136 from Davidiusdadi/master
bugfixes and more elaborate close callbacks and added onMessageFragment callback
2 parents 6e7cf0f + b014650 commit c9b4dbc

23 files changed

+453
-294
lines changed

README.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ The vm option `-Djavax.net.debug=all` can help to find out if there is a problem
9696

9797
It is currently not possible to accept ws and wss connections at the same time via the same websocket server instance.
9898

99+
For some reason firefox does not allow multible connections to the same wss server if the server uses a different port than the default port(443).
100+
99101
I ( @Davidiusdadi ) would be glad if you would give some feedback whether wss is working fine for you or not.
100102

101103
Minimum Required JDK

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>org.java_websocket</groupId>
6-
<artifactId>WebSocket</artifactId>
6+
<artifactId>Java-WebSocket</artifactId>
77
<version>1.0.0-SNAPSHOT</version>
88
<packaging>jar</packaging>
99
<name>Java WebSocket</name>

src/main/example/ChatServer.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import java.io.InputStreamReader;
44
import java.net.InetSocketAddress;
55
import java.net.UnknownHostException;
6-
import java.util.Set;
6+
import java.util.Collection;
77

88
import org.java_websocket.WebSocket;
99
import org.java_websocket.handshake.ClientHandshake;
@@ -61,6 +61,9 @@ public static void main( String[] args ) throws InterruptedException , IOExcepti
6161
@Override
6262
public void onError( WebSocket conn, Exception ex ) {
6363
ex.printStackTrace();
64+
if( websocket != null ) {
65+
// some errors like port binding failed may not be assignable to a specific websocket
66+
}
6467
}
6568

6669
/**
@@ -72,7 +75,7 @@ public void onError( WebSocket conn, Exception ex ) {
7275
* When socket related I/O errors occur.
7376
*/
7477
public void sendToAll( String text ) {
75-
Set<WebSocket> con = connections();
78+
Collection<WebSocket> con = connections();
7679
synchronized ( con ) {
7780
for( WebSocket c : con ) {
7881
c.send( text );

src/main/example/ExampleClient.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.java_websocket.drafts.Draft_10;
77
import org.java_websocket.handshake.ServerHandshake;
88

9+
/** This example demonstrates how to create a websocket connection to a server. Only the most important callbacks are overloaded. */
910
public class ExampleClient extends WebSocketClient {
1011

1112
public ExampleClient( URI serverUri , Draft draft ) {
@@ -18,22 +19,30 @@ public ExampleClient( URI serverURI ) {
1819

1920
@Override
2021
public void onOpen( ServerHandshake handshakedata ) {
22+
System.out.println( "opened connection" );
23+
// if you pan to refuse connection based on ip or httpfields overload: onWebsocketHandshakeReceivedAsClient
2124
}
2225

2326
@Override
2427
public void onMessage( String message ) {
28+
System.out.println( "received: " + message );
29+
// send( "you said: " + message );
2530
}
2631

2732
@Override
2833
public void onClose( int code, String reason, boolean remote ) {
34+
// The codecodes are documented in class org.java_websocket.framing.CloseFrame
35+
System.out.println( "Connection closed by " + ( remote ? "remote peer" : "us" ) );
2936
}
3037

3138
@Override
3239
public void onError( Exception ex ) {
40+
ex.printStackTrace();
41+
// if the error is fatal then onClose will be called additionally
3342
}
3443

3544
public static void main( String[] args ) throws URISyntaxException {
36-
ExampleClient c = new ExampleClient( new URI( "ws://localhost:8887" ), new Draft_10() );
45+
ExampleClient c = new ExampleClient( new URI( "ws://localhost:8887" ), new Draft_10() ); // more about drafts here: http://github.com/TooTallNate/Java-WebSocket/wiki/Drafts
3746
c.connect();
3847
}
3948

src/main/example/SSLClientExample.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public static void main( String[] args ) throws Exception {
7777
SSLContext sslContext = null;
7878
sslContext = SSLContext.getInstance( "TLS" );
7979
sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null );
80+
// sslContext.init( null, null, null ); // will use java's default key and trust store which is sufficient unless you deal with self-signed certificates
8081

8182
chatclient.setWebSocketFactory( new DefaultSSLWebSocketClientFactory( sslContext ) );
8283

src/main/example/SSLServerExample.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class SSLServerExample {
2121
public static void main( String[] args ) throws Exception {
2222
WebSocket.DEBUG = true;
2323

24-
ChatServer chatserver = new ChatServer( 8887 );
24+
ChatServer chatserver = new ChatServer( 8887 ); // Firefox does allow multible ssl connection only via port 443 //tested on FF16
2525

2626
// load up the key store
2727
String STORETYPE = "JKS";

src/main/java/org/java_websocket/SocketChannelIOHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public static boolean batch( WebSocketImpl ws, ByteChannel sockchannel ) throws
5353
} while ( buffer != null );
5454
}
5555

56-
if( ws.isClosed() ) {
56+
if( ws.outQueue.isEmpty() && ws.isFlushAndClose() ) {
5757
synchronized ( ws ) {
58-
sockchannel.close();
58+
ws.closeConnection();
5959
}
6060
}
6161
return sockchannel instanceof WrappedByteChannel == true ? !( (WrappedByteChannel) sockchannel ).isNeedWrite() : true;

src/main/java/org/java_websocket/WebSocket.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
package org.java_websocket;
22

33
import java.net.InetSocketAddress;
4+
import java.net.Socket;
45
import java.nio.ByteBuffer;
56
import java.nio.channels.NotYetConnectedException;
67

78
import org.java_websocket.drafts.Draft;
89
import org.java_websocket.exceptions.InvalidDataException;
9-
import org.java_websocket.exceptions.InvalidHandshakeException;
1010
import org.java_websocket.framing.Framedata;
11-
import org.java_websocket.handshake.ClientHandshakeBuilder;
1211

1312
public abstract class WebSocket {
1413
public enum Role {
1514
CLIENT, SERVER
1615
}
1716

17+
public enum READYSTATE {
18+
NOTYETCONNECTED, CONNECTING, OPEN, CLOSING, CLOSED;
19+
}
20+
1821
public static int RCVBUF = 16384;
1922

2023
public static/*final*/boolean DEBUG = false; // must be final in the future in order to take advantage of VM optimization
2124

22-
public static final int READY_STATE_CONNECTING = 0;
23-
public static final int READY_STATE_OPEN = 1;
24-
public static final int READY_STATE_CLOSING = 2;
25-
public static final int READY_STATE_CLOSED = 3;
2625
/**
2726
* The default port of WebSockets, as defined in the spec. If the nullary
2827
* constructor is used, DEFAULT_PORT will be the port the WebSocketServer
@@ -40,6 +39,12 @@ public enum Role {
4039

4140
public abstract void close( int code );
4241

42+
/**
43+
* This will close the connection immediately without a proper close handshake.
44+
* The code and the message therefore won't be transfered over the wire also they will be forwarded to onClose/onWebsocketClose.
45+
**/
46+
public abstract void closeConnection( int code, String message );
47+
4348
protected abstract void close( InvalidDataException e );
4449

4550
/**
@@ -64,10 +69,16 @@ public enum Role {
6469

6570
public abstract boolean hasBufferedData();
6671

67-
public abstract void startHandshake( ClientHandshakeBuilder handshakedata ) throws InvalidHandshakeException;
68-
72+
/**
73+
* @returns null when connections is closed
74+
* @see Socket#getRemoteSocketAddress()
75+
*/
6976
public abstract InetSocketAddress getRemoteSocketAddress();
7077

78+
/**
79+
* @returns null when connections is closed
80+
* @see Socket#getLocalSocketAddress()
81+
*/
7182
public abstract InetSocketAddress getLocalSocketAddress();
7283

7384
public abstract boolean isConnecting();
@@ -76,8 +87,15 @@ public enum Role {
7687

7788
public abstract boolean isClosing();
7889

90+
/**
91+
* Returns true when no further frames may be submitted<br>
92+
* This happens before the socket connection is closed.
93+
*/
94+
public abstract boolean isFlushAndClose();
95+
96+
/** Returns whether the close handshake has been completed and the socket is closed. */
7997
public abstract boolean isClosed();
80-
98+
8199
public abstract Draft getDraft();
82100

83101
/**
@@ -87,5 +105,5 @@ public enum Role {
87105
*
88106
* @return Returns '0 = CONNECTING', '1 = OPEN', '2 = CLOSING' or '3 = CLOSED'
89107
*/
90-
public abstract int getReadyState();
108+
public abstract READYSTATE getReadyState();
91109
}
Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package org.java_websocket;
22

3-
import java.nio.ByteBuffer;
4-
53
import org.java_websocket.drafts.Draft;
64
import org.java_websocket.exceptions.InvalidDataException;
75
import org.java_websocket.framing.Framedata;
86
import org.java_websocket.framing.Framedata.Opcode;
97
import org.java_websocket.framing.FramedataImpl1;
108
import org.java_websocket.handshake.ClientHandshake;
119
import org.java_websocket.handshake.HandshakeImpl1Server;
12-
import org.java_websocket.handshake.Handshakedata;
1310
import org.java_websocket.handshake.ServerHandshake;
1411
import org.java_websocket.handshake.ServerHandshakeBuilder;
1512

13+
/**
14+
* This class default implements all methods of the WebSocketListener that can be overridden optionally when advances functionalities is needed.<br>
15+
**/
1616
public abstract class WebSocketAdapter implements WebSocketListener {
1717

1818
/**
@@ -25,11 +25,6 @@ public ServerHandshakeBuilder onWebsocketHandshakeReceivedAsServer( WebSocket co
2525
return new HandshakeImpl1Server();
2626
}
2727

28-
/**
29-
* This default implementation does not do anything which will cause connections to be accepted. Go ahead and overwrite it.
30-
*
31-
* @see org.java_websocket.WebSocketListener#onWebsocketHandshakeReceivedAsClient(WebSocket, ClientHandshake, ServerHandshake)
32-
*/
3328
@Override
3429
public void onWebsocketHandshakeReceivedAsClient( WebSocket conn, ClientHandshake request, ServerHandshake response ) throws InvalidDataException {
3530
}
@@ -44,46 +39,19 @@ public void onWebsocketHandshakeSentAsClient( WebSocket conn, ClientHandshake re
4439
}
4540

4641
/**
47-
* This default implementation does not do anything. Go ahead and overwrite it.
42+
* This default implementation does not do anything. Go ahead and overwrite it
4843
*
49-
* @see org.java_websocket.WebSocketListener#onWebsocketMessage(WebSocket, String)
44+
* @see org.java_websocket.WebSocketListener#onWebsocketMessageFragment(WebSocket, Framedata)
5045
*/
5146
@Override
52-
public void onWebsocketMessage( WebSocket conn, String message ) {
53-
}
54-
55-
/**
56-
* This default implementation does not do anything. Go ahead and overwrite it.
57-
*
58-
* @see @see org.java_websocket.WebSocketListener#onWebsocketOpen(WebSocket, Handshakedata)
59-
*/
60-
@Override
61-
public void onWebsocketOpen( WebSocket conn, Handshakedata handshake ) {
62-
}
63-
64-
/**
65-
* This default implementation does not do anything. Go ahead and overwrite it.
66-
*
67-
* @see @see org.java_websocket.WebSocketListener#onWebsocketClose(WebSocket, int, String, boolean)
68-
*/
69-
@Override
70-
public void onWebsocketClose( WebSocket conn, int code, String reason, boolean remote ) {
71-
}
72-
73-
/**
74-
* This default implementation does not do anything. Go ahead and overwrite it.
75-
*
76-
* @see @see org.java_websocket.WebSocketListener#onWebsocketMessage(WebSocket, byte[])
77-
*/
78-
@Override
79-
public void onWebsocketMessage( WebSocket conn, ByteBuffer blob ) {
47+
public void onWebsocketMessageFragment( WebSocket conn, Framedata frame ) {
8048
}
8149

8250
/**
8351
* This default implementation will send a pong in response to the received ping.
8452
* The pong frame will have the same payload as the ping frame.
8553
*
86-
* @see @see org.java_websocket.WebSocketListener#onWebsocketPing(WebSocket, Framedata)
54+
* @see org.java_websocket.WebSocketListener#onWebsocketPing(WebSocket, Framedata)
8755
*/
8856
@Override
8957
public void onWebsocketPing( WebSocket conn, Framedata f ) {
@@ -119,13 +87,4 @@ public String getFlashPolicy( WebSocket conn ) {
11987
return "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"" + conn.getLocalSocketAddress().getPort() + "\" /></cross-domain-policy>\0";
12088
}
12189

122-
/**
123-
* This default implementation does not do anything. Go ahead and overwrite it.
124-
*
125-
* @see @see org.java_websocket.WebSocketListener#onWebsocketError(WebSocket, Exception)
126-
*/
127-
@Override
128-
public void onWebsocketError( WebSocket conn, Exception ex ) {
129-
}
130-
13190
}

0 commit comments

Comments
 (0)