WebSockets are full-duplex: client and server can both send messages anytime. They start as a normal HTTP request with Connection: Upgrade and Upgrade: websocket headers; the server responds 101 Switching Protocols and the underlying TCP connection becomes a raw WebSocket frame stream.
Use cases that need the bidirectional channel: chat apps, collaborative editing (cursors, simultaneous typing), game state sync, realtime dashboards where the client also publishes (typing indicators, presence). One-way push? Use Server-Sent Events instead — simpler.
Reverse-tunnel services that proxy WebSockets correctly are a smaller set than you'd think. Some buffer or terminate Upgrade frames. lrok forwards WebSocket frames byte-for-byte through yamux streams, which is why HMR (which uses WebSockets) works through lrok.