Send updates about (for now, only) blocks via WebSocket.
The indexer handles subscriptions using the `Subs` struct, which allows to get `tokio::sync::broadcast::Receiver`s for `BlockMsg`. When a block is connected/disconnected/finalized, the indexer tells `Subs` to broadcast a `BlockMsg` to all the subscribers.
When a client connects via WebSocket, we handle that connection's livecycle in `handle_subscribe_socket`. We listen to both messages from the client as well as from the indexer using `select!`. To separate the ws handling and the subscription logic, we add `WsMsg`.
Errors (e.g. the client sending an unknown/invalid message) are handled by sending the client a `proto::Error` message.
For testing, we add `websocket-client` via pip, and add a `ws` method to `ChronikClient`.