From 38f6455c83dd68c80b2f667388d45cf6a28688ee Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Wed, 4 Dec 2024 14:17:02 -0800 Subject: Better websocket reader fix bug double-render --- .../com/seaofnodes/simple/SimpleWebSocket.java | 36 +++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'chapter18/src/main/java/com') diff --git a/chapter18/src/main/java/com/seaofnodes/simple/SimpleWebSocket.java b/chapter18/src/main/java/com/seaofnodes/simple/SimpleWebSocket.java index f9a85d19..1ce766ff 100644 --- a/chapter18/src/main/java/com/seaofnodes/simple/SimpleWebSocket.java +++ b/chapter18/src/main/java/com/seaofnodes/simple/SimpleWebSocket.java @@ -55,15 +55,35 @@ class SimpleWebSocket extends ServerSocket { int _x, _len; private int rawget() { assert _x<_len; return _ins[_x++]&0xFF; } + // TODO: Flip to Direct Byte Buffer, this is just a poor-mans version + private void flipRead() throws IOException { + // Move _x to _len to offset 0 + System.arraycopy(_ins,_x,_ins,0,(_len-_x)); + _len = _len-_x; + _x=0; + // Read more + int len = _in.read(_ins,_len,_ins.length-_len); + if( len == -1 ) + throw Utils.TODO(); // EOF + _len += len; + } + // Block until you read at least len + private void atLeast(int len) throws IOException { + if( _x+len <= _len ) return; + flipRead(); + } + + // Classic read from browser client. Encoded, so decoded here public String get() throws IOException { - _len = _in.read(_ins); _x=0; + atLeast(1); // Need 1 byte for opcode int op = rawget(); - if( (op&0x80)!=0x80 ) // FIN bit not set? - throw Utils.TODO("Multi-part from client: "+op); // Multipart message - op &= 0x7F; // Strip FIN bit + if( (op&0x80)!=0x80 ) // FIN bit not set? + throw Utils.TODO( "Multi-part from client: " + op ); // Multipart message + op &= 0x7F; // Strip FIN bit switch( op&15) { case 1: { + atLeast(5); // Min message length // Message length int len = rawget()-128; if( len > 125 ) { @@ -71,11 +91,13 @@ class SimpleWebSocket extends ServerSocket { throw Utils.TODO(); // Multi-byte length len = (rawget()<<8) | rawget(); } + atLeast(len+4); // Rest of message // Encoding key _key[0] = (byte)rawget(); _key[1] = (byte)rawget(); _key[2] = (byte)rawget(); _key[3] = (byte)rawget(); + // Decode bytes for( int i=0; i