diff options
| author | Cliff Click <cliffc@acm.org> | 2024-12-04 14:17:02 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-01-15 15:07:30 -0800 |
| commit | 38f6455c83dd68c80b2f667388d45cf6a28688ee (patch) | |
| tree | f3f3662706928fc95398354a3268973b13075179 /chapter18 | |
| parent | d2df2a776bf2bd2d382de948d1ad83e54eb38ffc (diff) | |
| download | Simple-38f6455c83dd68c80b2f667388d45cf6a28688ee.tar.gz Simple-38f6455c83dd68c80b2f667388d45cf6a28688ee.zip | |
Better websocket reader
fix bug double-render
Diffstat (limited to 'chapter18')
| -rw-r--r-- | chapter18/docs/index.html | 2 | ||||
| -rw-r--r-- | chapter18/src/main/java/com/seaofnodes/simple/SimpleWebSocket.java | 36 |
2 files changed, 33 insertions, 5 deletions
diff --git a/chapter18/docs/index.html b/chapter18/docs/index.html index c2441202..06e19e2c 100644 --- a/chapter18/docs/index.html +++ b/chapter18/docs/index.html @@ -153,7 +153,7 @@ document.getElementById("program").focus(); document.getElementById("program").setSelectionRange(pos,pos+1); } - graphviz.renderDot(dots[idx]).on("end", _rendNext(idx,end,step)) + graphviz.renderDot(dots[idx]).on("end", () => _rendNext(idx,end,step)) } } function _rendNext(idx,end,step) { 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<len; i++ ) _str[i] = (byte)(rawget() ^ _key[i & 3]); @@ -84,6 +106,12 @@ class SimpleWebSocket extends ServerSocket { } // Client closes case 8: return null; + // Ping + case 9: + // Send a PONG back. TODO: echo PING data in the PONG + _out.write(0x8A); // FIN + PONG + _out.write(0x00); // LENGTH==0 + return get(); // Not (yet) implemented: continuation frames, ping/pong default: throw Utils.TODO("Unexpected op from client: "+op); // Multi-part message |
