RPC specification is simple enough, and made very close to jsonrpc
Simple request. Ask server to call some function and return results in blocking fashion.
+---+-------+--------+--------+
| 0 | msgid | method | params |
+---+-------+--------+--------+
Call multiply function with one param 2.
>>> msgpack.loads('\x94\x00\x0c\xa8multiply\x91\x02')
(0, 12, 'multiply', (2,))
Simple reply. Server sends reply after call was completed.
+---+-------+-------+--------+
| 1 | msgid | error | result |
+---+-------+-------+--------+
This is reply for request example above
>>> msgpack.loads('\x94\x01\x0c\xc0\x04')
(1, 12, None, 4)
Variant of simple request, for which client dont want to wait result. This way client sends notification, may disconnect immidiately, while servers run requested function in asynchronous way. But client will not be able to receive results (server dont even try to send them).
+---+--------+--------+
| 2 | method | params |
+---+--------+--------+
>>> msgpack.loads('\x93\x02\xa8shutdown\x90')
(2, 'shutdown', ())
All MessagePack RPC above is supported (of course...). But in addition to original specification joint has its own extensions.
Extended request:
+------------+---------+-------+--------+---------+-----------+
| offset + 0 | req_opt | msgid | method | params? | kwparams? |
+------------+---------+-------+--------+---------+-----------+
+------------+-------+------+
| offset + 0 | msgid | data |
+------------+-------+------+
+------------+---------+-------+--------+
| offset + 1 | rep_opt | msgid | result |
+------------+---------+-------+--------+
Value : | 1 |
---|
Value : | 2 |
---|
If remote function returned generator, there will be multiple reply packets with final reply with result set to null. Once client received yield packet it can throw something back using Request throw packet.
Pings normally should be asynchronous. Main idea is simple: in classic rpc it is too hard to detect if connection “stucks”. You call some meth, but you dont really now how much time it will be executed.
Normal scenario:
--> call something
<-- ok, calling
<-- (after some time) here is a result
But what if connection hangs after meth was called, but before result was made:
--> call something
<-- ok, calling
(connection freezes)
Right now we dont know how much to wait. Because we cant detect what’s happening on server side. With pings this can be done easily:
--> call something
<-- ok, calling
(after ping interval)
--> ping
<-- pong
(after ping interval, meanwhile connection freezes)
--> ping
(wait on client side for pong for hardcoded ping timeout and abort)
Pings always issued by client side. Pongs – by server side.
+------------+
| offset + 3 |
+------------+
+------------+
| offset + 4 |
+------------+