Skip to content

Commit

Permalink
server sendTo and sendToAll methods now will use fragments if needed
Browse files Browse the repository at this point in the history
This change allows supporting sending large messages by sending keepalive messages in between fragments. Previously, the timeout mechanism in Java-WebSocket would close the connection automatically because no ping-pongs would be exchanged while the client was receiving a large message.
  • Loading branch information
jebej committed May 28, 2020
1 parent 8282a50 commit 820bb33
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 9 deletions.
Binary file removed jar/matlab-websocket-1.4.jar
Binary file not shown.
Binary file added jar/matlab-websocket-1.5.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion src/matlab-websocket/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<groupId>io.github.jebej.matlabwebsocket</groupId>
<artifactId>matlab-websocket</artifactId>
<packaging>jar</packaging>
<version>1.4</version>
<version>1.5</version>

<name>matlab-websocket</name>
<url>https://github.com/jebej/MatlabWebSocket</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.java_websocket.framing.PongFrame;
import org.java_websocket.enums.Opcode;

public class MatlabWebSocketServer extends WebSocketServer {
// The constructor creates a new WebSocketServer with the wildcard IP,
Expand Down Expand Up @@ -76,9 +78,9 @@ public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
public WebSocket getConnection( int hashCode ) {
Collection<WebSocket> conns = getConnections();
synchronized ( conns ) {
for( WebSocket c : conns ) {
if (c.hashCode() == hashCode) {
return c;
for ( WebSocket conn : conns ) {
if (conn.hashCode() == hashCode) {
return conn;
}
}
}
Expand All @@ -92,7 +94,8 @@ public void sendTo( int hashCode, String message ) {

// Send binary message to a connection identified by a hashcode
public void sendTo( int hashCode, ByteBuffer blob ) {
getConnection( hashCode ).send( blob );
WebSocket conn = getConnection( hashCode );
sendSplit( conn, blob );
}

// Send binary message to a connection identified by a hashcode
Expand All @@ -104,8 +107,8 @@ public void sendTo( int hashCode, byte[] bytes ) {
public void sendToAll( String message ) {
Collection<WebSocket> conns = getConnections();
synchronized ( conns ) {
for( WebSocket c : conns ) {
c.send( message );
for( WebSocket conn : conns ) {
conn.send( message );
}
}
}
Expand All @@ -114,8 +117,8 @@ public void sendToAll( String message ) {
public void sendToAll( ByteBuffer blob ) {
Collection<WebSocket> conns = getConnections();
synchronized ( conns ) {
for( WebSocket c : conns ) {
c.send( blob );
for( WebSocket conn : conns ) {
sendSplit( conn, blob );
}
}
}
Expand All @@ -124,6 +127,28 @@ public void sendToAll( ByteBuffer blob ) {
public void sendToAll( byte[] bytes ) {
sendToAll( ByteBuffer.wrap( bytes ) );
}

// Method to send large messages in fragments if needed
public void sendSplit( WebSocket conn, ByteBuffer blob ) {
int FRAG_SIZE = 5*1024*1024; // 5MB
int blobSize = blob.capacity();
// Only send as fragments if message is larger than FRAG_SIZE
if ( blobSize <= FRAG_SIZE ) {
conn.send( blob );
} else {
int numFrags = (blobSize + FRAG_SIZE - 1)/FRAG_SIZE;
blob.rewind();
for ( int i = 0; i<numFrags; i++ ) {
blob.position( i*FRAG_SIZE );
blob.limit( Math.min( (i+1)*FRAG_SIZE, blobSize ) );
conn.sendFragmentedFrame( Opcode.BINARY, blob, (i+1)==numFrags );
// Send a ping AND an unpromted pong to keep connection alive
conn.sendPing();
conn.sendFrame( new PongFrame() );
}
assert( blob.position() == blobSize );
}
}

// Close connection identified by a hashcode
public void close( int hashCode ) {
Expand Down

0 comments on commit 820bb33

Please sign in to comment.