@@ -947,17 +947,28 @@ private void send(int opcode, byte[] payload) throws IOException {
947947 * @throws IOException
948948 */
949949 private void read () throws IOException {
950+ // If message contains fragmented parts we should put it all together.
951+ LinkedList <byte []> messageParts = new LinkedList <>();
952+
950953 // The first byte of every data frame
951954 int firstByte ;
955+ int opcode = 0 ;
952956
953957 // Loop until end of stream is reached.
954958 while ((firstByte = bis .read ()) != -1 ) {
955959 // Data contained in the first byte
956- // int fin = (firstByte << 24) >>> 31;
960+ // If the flag is on we have more frames for this message.
961+ int fin = (firstByte << 24 ) >>> 31 ;
957962 // int rsv1 = (firstByte << 25) >>> 31;
958963 // int rsv2 = (firstByte << 26) >>> 31;
959964 // int rsv3 = (firstByte << 27) >>> 31;
960- int opcode = (firstByte << 28 ) >>> 28 ;
965+
966+ // Only first frame will have real opcode (text or binary),
967+ // In next frames opcode will be zero (continuation)
968+ if (messageParts .isEmpty ())
969+ opcode = (firstByte << 28 ) >>> 28 ;
970+
971+ boolean isLast = fin == 1 ;
961972
962973 // Reads the second byte
963974 int secondByte = bis .read ();
@@ -1010,10 +1021,39 @@ private void read() throws IOException {
10101021 data [i ] = b ;
10111022 }
10121023
1024+ if (isLast ) {
1025+ // If we already have some fragments, just add last and put it together
1026+ if (!messageParts .isEmpty ()) {
1027+ messageParts .add (data );
1028+ // Calculate total size of all parts
1029+ int fullSize = 0 ;
1030+ int offset = 0 ;
1031+ for (byte [] fragment : messageParts )
1032+ fullSize += fragment .length ;
1033+
1034+ byte [] fullMessage = new byte [fullSize ];
1035+
1036+ // Copy all parts into one array
1037+ for (byte [] fragment : messageParts ) {
1038+ System .arraycopy (fragment , 0 , fullMessage , offset , fragment .length );
1039+ offset += fragment .length ;
1040+ }
1041+
1042+ data = fullMessage ;
1043+ messageParts .clear ();
1044+ }
1045+ // else: Single framed message - do nothing
1046+ } else {
1047+ // Collect this fragment and go read next frame.
1048+ messageParts .add (data );
1049+ continue ;
1050+ }
1051+
10131052 // Execute the action depending on the opcode
10141053 switch (opcode ) {
10151054 case OPCODE_CONTINUATION :
1016- // Should be implemented
1055+ // Implemented above
1056+ // I think this case should never happen
10171057 break ;
10181058 case OPCODE_TEXT :
10191059 notifyOnTextReceived (new String (data , Charset .forName ("UTF-8" )));
0 commit comments