Open preaction opened 7 years ago
If we do this, we should add a simple JS client library accessible at /js/client.js
to make using the multiplexer easier. The client should have a subscribe
method that takes an endpoint and accepts a callback, an unsubscribe
method to unsubscribe from a topic, and a send
method that sends a message on a topic.
As many have pointed out, the only way to use Mercury requires opening multiple connections to the same Mercury broker. This is intentional: Mercury is internally simple, and its API requires no formatting of messages so that anything can pass through it. Trying to read the content of messages restricts what people can use Mercury for, which limits its usefulness as a broker (I'm going for ZeroMQ, not RabbitMQ).
However, like ZeroMQ has router/dealer, so too could Mercury have a very small envelope to enable some kind of multiplexing. By connecting to
/multi
, a client opens a multiplexing session. They can then send requests for any other Mercury endpoint in websocket messages. Each request will be routed as though it was sent through its own connection.To send a request, the client adds the absolute URL to the desired endpoint, followed by
\r\n
(\015\012
, the HTTP end of line sequence), and followed by the body of the message, if any. Any messages received by the client will also have the endpoint the message was intended for, followed by\r\n
, followed by the body of the message.To subscribe to topics (
/bus
,/sub
,/pull
) without sending a message on the topic, the client can send an empty message. The message must have the\r\n
that separates the endpoint and the body. For/sub
and/pull
, any message body will be ignored (these are uni-directional subscriptions). For/bus
specifically, if a body is included, it will be sent out to all subscribers.Since
/multi
will never be used inside of a multiplexed connection, we can use it to control the connection itself. To unsubscribe from a topic (/bus
,/sub
,/pull
) without closing the connection, the client can send an empty message with/multi/stop
prepended to the endpoint (like/multi/stop/bus/foo
to stop the/bus/foo
messages from arriving).For example:
/bus/leela\015\012
/bus/leela\015\012Hello, World
/multi/stop/bus/leela\015\012
This could be the mechanism used to connect different brokers together (#35) (again, much like ZeroMQ's router/dealer model).