Initial web socket API.

This PR is to a `websocket` feature branch for later merging into `master`.
I think it could still be the same thread, it's just that calling payload.read() might cause some control frames to be processed.