You can genuinely implement the protocol with good performance in 150/200 lines, from memory;
1. Read the opcode
2. If PING, send PONG. If binary or text, continue
3. Read the header size
4. Read the payload size (which is a variable-width integer, hence getting the header size first)
5. Unmask the payload
6. If fin in the header is false, add the payload to a buffer. Else, either immediately dispatch (continuation buffer is empty) or buffer and dispatch (continuation buffer isn’t empty)
There are extensions like setting RSV1 to indicate you need to decompress the payload, but that’s the only one I’ve encountered building clients for >20 WebSocket based APIs.
I’ve had more difficulty building http1.1 implementations that broadly work, still a lot of weird stuff like incorrect chucked message parsing you have to handle on the server side. Yeah plain TCP is obviously simpler but you can’t consume a raw socket in a browser, that’s why web sockets win for me - easy to consume over api and browser.