We use zeromq’s request reply model for http forwarding (except for long polling case)
For each http request zerogw forwards a single multipart message. Request_id is sent like address data (message parts that can be read using XREP sockets only, and finished by empty message). After address data configured parts of the request are sent one by one as multipart message. E.g. if you have following in configuration:
zmq-forward:
contents:
- !Method
- !Uri
- !Header Cookie
- !Body
And you’ve got request:
POST /hello HTTP/1.1
Host: example.com
Cookie: example=cookie_value
Content-Length: 8
PostBody
You will receive following message parts (one line per message part):
POST
/hello
example=cookie_value
PostBody
It’s up to the application for how to act upon it. Note if you set retry to something you can get same request twice. And if retry is set to !RetryFirst <N> request id will be same for every attempt, if you’ve set retry to !RetryLast <N> request id will change on each attempt. But usually request id is opaque for user in zeromq.
Response can contain one, two or three parts for convenience.
In the simple case you just send message body, as a single part message. Zerogw will respond with 200 OK and that message body.
If you respond with two messages first one will be status line, so yo can respond with 404 page like the following:
404 Not Found
<h1> Page Not Found</h1>
Note
These ways are quite unuseful in real situations. Content-Length header will be added automatically, but you should configure specific Content-Type header in a config to be sure that browser will render page correctly when using this method
If you need to supply headers you send 3 message parts. Second one is constructed from nul-terminated name/value header pairs:
200 OK
Content-Type\0text/html\0E-tag\0immortal\0
<b>Lorem ipsum dolor sit amet</b>
Note
Last header value must be nul-terminated. You must not add Content-Length header as it will be generated automatically. Currently headers sent from backend will be appended to headers specified in config without overwriting, it can lead to unexpected behavior on some proxies or browsers so you should use use one or another way for each header type throught the whole application.
Zerogw implements unified interface for application writers for both long polling and websockets. Both are used for bidirectional message channels from client to server.
Note
There is no overhead of using long polling with normal http backend in zerogw if that suits your application. This interface is provided to make using either websockets or long polling transparent for both frontend and backend developer and provides reliable message stream.
Most messages from server to client consists of client id (long binary string of nonsense) and ascii command name, following more message parts which we will call arguments in the text below.
is sent when connection disconnected. All subscriptions (see below) are already cancelled so you don’t need to remove them, but you can cleanup some application-specific data. No arguments
Starting with v0.5.10: disconnect appends an cookie (see below) as an argument, if cookie is set (it breaks compatibility somewhat with versions starting with v0.5.8, which did not return cookie on the disconnect)
There are two kinds of heartbeat messages:
Both start with server id message. For the former server id is followed by literal ascii heartbeat. Latter consists of literal ascii sync followed by pairs connection_id, cookie (latter is empty if cookie is not sent, but is always sent).
Sync messages are only sent to named outputs (see below), and can be used to synchronize user list with backend in case of network failures (connect or disconnect message lost), backend failures (could not process connect or disconnect message, because backend crashed when processing message) or zerogw crashes (zerogw can’t send disconnect messages after restart).
Usually messages sent from backend are published using pubsub to several zerogw. This allows not to track where user currently is and also allows to publish messages to several users without doing that on backend.
Topics is a mechanism in zerogw which allows you to send message to several users effeciently. You first subscribe users to a topic, send publish a message to a topic, and all users get this message. Topic is an opaque binary string. Topics are created and removed on demand and are quite fast to use them for a lot of things.
In addition to subscription clients on topics you can subscribe subset of client messages to a specific named backend (named-outputs in config)
As with subscriptions don’t need to unmap anything from disconnected user.
Note
it’s your responsibility to clean user state from the backend. disconnect messages are sent to main backend only
Cookie is a experimental feature of zerogw v0.5.8, which allows to prepend opaque data to all messages sent from a client. This is usually used to authorize connection without need to access authorization database on each user’s message. Only one cookie can be attached at a time, but you can change the cookie at any time. Once set, you can’t discard cookie. Once cookie attached all messages will be forwarded using msgfrom message type with cookie and data.
Note
starting with v0.5.10 cookie set with set_cookie are sent in disconnect messages. Since disconnect can occur before you were able to set cookie you must tolerate different number of arguments in disconnect messsages.