Skip to content

Commit b014650

Browse files
committed
Removed caching of fragmented frames. Fragmented frames now have their own callback onWebsocketMessageFragment
1 parent 3277828 commit b014650

File tree

3 files changed

+42
-46
lines changed

3 files changed

+42
-46
lines changed

src/main/java/org/java_websocket/WebSocketImpl.java

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.java_websocket.drafts.Draft_76;
2323
import org.java_websocket.exceptions.IncompleteHandshakeException;
2424
import org.java_websocket.exceptions.InvalidDataException;
25-
import org.java_websocket.exceptions.InvalidFrameException;
2625
import org.java_websocket.exceptions.InvalidHandshakeException;
2726
import org.java_websocket.exceptions.WebsocketNotConnectedException;
2827
import org.java_websocket.framing.CloseFrame;
@@ -89,8 +88,7 @@ public class WebSocketImpl extends WebSocket {
8988

9089
private Role role;
9190

92-
/** used to join continuous frames */
93-
private Framedata tempContiniousFrame;// FIXME out of mem risk
91+
private Opcode current_continuous_frame_opcode = null;
9492

9593
/** the bytes of an incomplete received handshake */
9694
private ByteBuffer tmpHandshakeBytes;
@@ -292,7 +290,7 @@ private boolean decodeHandshake( ByteBuffer socketBufferNew ) {
292290
private void decodeFrames( ByteBuffer socketBuffer ) {
293291
if( flushandclosestate )
294292
return;
295-
assert ( !isClosed() );
293+
296294
List<Framedata> frames;
297295
try {
298296
frames = draft.translateFrame( socketBuffer );
@@ -302,6 +300,8 @@ private void decodeFrames( ByteBuffer socketBuffer ) {
302300
if( flushandclosestate )
303301
return;
304302
Opcode curop = f.getOpcode();
303+
boolean fin = f.isFin();
304+
305305
if( curop == Opcode.CLOSING ) {
306306
int code = CloseFrame.NOCODE;
307307
String reason = "";
@@ -327,27 +327,40 @@ private void decodeFrames( ByteBuffer socketBuffer ) {
327327
} else if( curop == Opcode.PONG ) {
328328
wsl.onWebsocketPong( this, f );
329329
continue;
330-
} else {
331-
// process non control frames
332-
if( tempContiniousFrame == null ) {
333-
if( f.getOpcode() == Opcode.CONTINUOUS ) {
334-
throw new InvalidFrameException( "unexpected continious frame" );
335-
} else if( f.isFin() ) {
336-
// receive normal onframe message
337-
deliverMessage( f );
338-
} else {
339-
// remember the frame whose payload is about to be continued
340-
tempContiniousFrame = f;
341-
}
342-
} else if( f.getOpcode() == Opcode.CONTINUOUS ) {
343-
tempContiniousFrame.append( f );
344-
if( f.isFin() ) {
345-
deliverMessage( tempContiniousFrame );
346-
tempContiniousFrame = null;
347-
}
348-
} else {
349-
throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected" );
330+
} else if( !fin || curop == Opcode.CONTINUOUS ) {
331+
if( curop != Opcode.CONTINUOUS ) {
332+
if( current_continuous_frame_opcode != null )
333+
throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed." );
334+
current_continuous_frame_opcode = curop;
335+
} else if( fin ) {
336+
if( current_continuous_frame_opcode == null )
337+
throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started." );
338+
current_continuous_frame_opcode = null;
339+
} else if( current_continuous_frame_opcode == null ) {
340+
throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started." );
341+
}
342+
try {
343+
wsl.onWebsocketMessageFragment( this, f );
344+
} catch ( RuntimeException e ) {
345+
wsl.onWebsocketError( this, e );
346+
}
347+
348+
} else if( current_continuous_frame_opcode != null ) {
349+
throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed." );
350+
} else if( curop == Opcode.TEXT ) {
351+
try {
352+
wsl.onWebsocketMessage( this, Charsetfunctions.stringUtf8( f.getPayloadData() ) );
353+
} catch ( RuntimeException e ) {
354+
wsl.onWebsocketError( this, e );
350355
}
356+
} else if( curop == Opcode.BINARY ) {
357+
try {
358+
wsl.onWebsocketMessage( this, f.getPayloadData() );
359+
} catch ( RuntimeException e ) {
360+
wsl.onWebsocketError( this, e );
361+
}
362+
} else {
363+
throw new InvalidDataException( CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected" );
351364
}
352365
}
353366
} catch ( InvalidDataException e1 ) {
@@ -431,7 +444,6 @@ protected synchronized void closeConnection( int code, String message, boolean r
431444
}
432445
if( draft != null )
433446
draft.reset();
434-
tempContiniousFrame = null;
435447
handshakerequest = null;
436448

437449
readystate = READYSTATE.CLOSED;
@@ -471,7 +483,6 @@ protected synchronized void flushAndClose( int code, String message, boolean rem
471483
}
472484
if( draft != null )
473485
draft.reset();
474-
tempContiniousFrame = null;
475486
handshakerequest = null;
476487
}
477488

@@ -611,22 +622,6 @@ private void write( List<ByteBuffer> bufs ) {
611622
}
612623
}
613624

614-
private void deliverMessage( Framedata d ) throws InvalidDataException {
615-
try {
616-
if( d.getOpcode() == Opcode.TEXT ) {
617-
wsl.onWebsocketMessage( this, Charsetfunctions.stringUtf8( d.getPayloadData() ) );
618-
} else if( d.getOpcode() == Opcode.BINARY ) {
619-
wsl.onWebsocketMessage( this, d.getPayloadData() );
620-
} else {
621-
if( DEBUG )
622-
System.out.println( "Ignoring frame:" + d.toString() );
623-
assert ( false );
624-
}
625-
} catch ( RuntimeException e ) {
626-
wsl.onWebsocketError( this, e );
627-
}
628-
}
629-
630625
private void open( Handshakedata d ) {
631626
if( DEBUG )
632627
System.out.println( "open using draft: " + draft.getClass().getSimpleName() );

src/main/java/org/java_websocket/WebSocketListener.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public interface WebSocketListener {
2020
/**
2121
* Called on the server side when the socket connection is first established, and the WebSocket
2222
* handshake has been received. This method allows to deny connections based on the received handshake.<br>
23-
* By behavior this method only requires protocol compliance.
23+
* By default this method only requires protocol compliance.
2424
*
2525
* @param conn
2626
* The WebSocket related to this event
@@ -84,6 +84,8 @@ public interface WebSocketListener {
8484
*/
8585
public void onWebsocketMessage( WebSocket conn, ByteBuffer blob );
8686

87+
public void onWebsocketMessageFragment( WebSocket conn, Framedata frame );
88+
8789
/**
8890
* Called after <var>onHandshakeReceived</var> returns <var>true</var>.
8991
* Indicates that a complete WebSocket connection has been established,

src/main/java/org/java_websocket/client/WebSocketClient.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ public abstract class WebSocketClient extends WebSocketAdapter implements Runnab
4949
* The URI this channel is supposed to connect to.
5050
*/
5151
private URI uri = null;
52-
/**
53-
* The WebSocket instance this channel object wraps.
54-
*/
52+
5553
private WebSocketImpl conn = null;
5654
/**
5755
* The SocketChannel instance this channel uses.
@@ -416,6 +414,7 @@ public void onCloseInitiated( int code, String reason ) {
416414
public void onClosing( int code, String reason, boolean remote ) {
417415
}
418416

417+
419418
public WebSocket getConnection() {
420419
return conn;
421420
}

0 commit comments

Comments
 (0)