preaction / Mercury

A message broker for WebSockets
Other
10 stars 8 forks source link

Multiplexing endpoint #40

Open preaction opened 7 years ago

preaction commented 7 years ago

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:

This could be the mechanism used to connect different brokers together (#35) (again, much like ZeroMQ's router/dealer model).

preaction commented 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.