@@ -943,17 +943,28 @@ private void send(int opcode, byte[] payload) throws IOException {
943
943
* @throws IOException
944
944
*/
945
945
private void read () throws IOException {
946
+ // If message contains fragmented parts we should put it all together.
947
+ LinkedList <byte []> messageParts = new LinkedList <byte []>();
948
+
946
949
// The first byte of every data frame
947
950
int firstByte ;
951
+ int opcode = 0 ;
948
952
949
953
// Loop until end of stream is reached.
950
954
while ((firstByte = bis .read ()) != -1 ) {
951
955
// Data contained in the first byte
952
- // int fin = (firstByte << 24) >>> 31;
956
+ // If the flag is on we have more frames for this message.
957
+ int fin = (firstByte << 24 ) >>> 31 ;
953
958
// int rsv1 = (firstByte << 25) >>> 31;
954
959
// int rsv2 = (firstByte << 26) >>> 31;
955
960
// int rsv3 = (firstByte << 27) >>> 31;
956
- int opcode = (firstByte << 28 ) >>> 28 ;
961
+
962
+ // Only first frame will have real opcode (text or binary),
963
+ // In next frames opcode will be zero (continuation)
964
+ if (messageParts .isEmpty ())
965
+ opcode = (firstByte << 28 ) >>> 28 ;
966
+
967
+ boolean isLast = fin == 1 ;
957
968
958
969
// Reads the second byte
959
970
int secondByte = bis .read ();
@@ -969,10 +980,7 @@ private void read() throws IOException {
969
980
if (payloadLength == 126 ) {
970
981
// Attempts to read the next 2 bytes
971
982
byte [] nextTwoBytes = new byte [2 ];
972
- for (int i = 0 ; i < 2 ; i ++) {
973
- byte b = (byte ) bis .read ();
974
- nextTwoBytes [i ] = b ;
975
- }
983
+ if (bis .read (nextTwoBytes ) == -1 ) break ;
976
984
977
985
// Those last 2 bytes will be interpreted as a 16-bit
978
986
// unsigned
@@ -982,10 +990,7 @@ private void read() throws IOException {
982
990
} else if (payloadLength == 127 ) {
983
991
// Attempts to read the next 8 bytes
984
992
byte [] nextEightBytes = new byte [8 ];
985
- for (int i = 0 ; i < 8 ; i ++) {
986
- byte b = (byte ) bis .read ();
987
- nextEightBytes [i ] = b ;
988
- }
993
+ if (bis .read (nextEightBytes ) == -1 ) break ;
989
994
990
995
// Only the last 4 bytes matter because Java doesn't support
991
996
// arrays with more than 2^31 -1 elements, so a 64-bit
@@ -1001,15 +1006,41 @@ private void read() throws IOException {
1001
1006
1002
1007
// Attempts to read the payload data
1003
1008
byte [] data = new byte [payloadLength ];
1004
- for (int i = 0 ; i < payloadLength ; i ++) {
1005
- byte b = (byte ) bis .read ();
1006
- data [i ] = b ;
1009
+ if (bis .read (data ) == -1 ) break ;
1010
+
1011
+ if (isLast ) {
1012
+ // If we already have some fragments, just add last and put it together
1013
+ if (!messageParts .isEmpty ()) {
1014
+ messageParts .add (data );
1015
+ // Calculate total size of all parts
1016
+ int fullSize = 0 ;
1017
+ int offset = 0 ;
1018
+ for (byte [] fragment : messageParts )
1019
+ fullSize += fragment .length ;
1020
+
1021
+ byte [] fullMessage = new byte [fullSize ];
1022
+
1023
+ // Copy all parts into one array
1024
+ for (byte [] fragment : messageParts ) {
1025
+ System .arraycopy (fragment , 0 , fullMessage , offset , fragment .length );
1026
+ offset += fragment .length ;
1027
+ }
1028
+
1029
+ data = fullMessage ;
1030
+ messageParts .clear ();
1031
+ }
1032
+ // else: Single framed message - do nothing
1033
+ } else {
1034
+ // Collect this fragment and go read next frame.
1035
+ messageParts .add (data );
1036
+ continue ;
1007
1037
}
1008
1038
1009
1039
// Execute the action depending on the opcode
1010
1040
switch (opcode ) {
1011
1041
case OPCODE_CONTINUATION :
1012
- // Should be implemented
1042
+ // Implemented above
1043
+ // I think this case should never happen
1013
1044
break ;
1014
1045
case OPCODE_TEXT :
1015
1046
notifyOnTextReceived (new String (data , Charset .forName ("UTF-8" )));
0 commit comments