@@ -81,6 +81,10 @@ The IPROTO constants that identify requests that we will mention in this section
8181 IPROTO_FETCH_SNAPSHOT=0x45
8282 IPROTO_REGISTER=0x46
8383 IPROTO_ID=0x49
84+ IPROTO_WATCH=0x4a
85+ IPROTO_UNWATCH=0x4b
86+ IPROTO_EVENT=0x4c
87+
8488
8589 The IPROTO constants that appear within requests or responses that we will describe in this section are:
8690
@@ -146,7 +150,9 @@ The IPROTO constants that appear within requests or responses that we will descr
146150 IPROTO_VERSION=0x54
147151 IPROTO_FEATURES=0x55
148152 IPROTO_TIMEOUT=0x56
149- IPROTO_TXN_ISOLATION = 0x59
153+ IPROTO_EVENT_KEY=0x57
154+ IPROTO_EVENT_DATA=0x58
155+ IPROTO_TXN_ISOLATION=0x59
150156
151157
152158 To denote message descriptions we will say ``msgpack(...) `` and within it we will use modified
@@ -935,13 +941,137 @@ Available IPROTO_FEATURES are the following:
935941 MsgPack extension support. Clients that don't support this feature will receive
936942 error responses for :ref: `IPROTO_EVAL <box_protocol-eval >` and
937943 :ref: `IPROTO_CALL <box_protocol-call >` encoded to string error messages.
938- - ``IPROTO_FEATURE_WATCHERS = 3 `` -- remote watchers support: IPROTO_WATCH,
939- IPROTO_UNWATCH, and IPROTO_EVENT commands.
940-
941- .. // TODO: document remote watchers commands
944+ - ``IPROTO_FEATURE_WATCHERS = 3 `` -- remote watchers support: :ref: `IPROTO_WATCH <box_protocol-watch >`,
945+ :ref: `IPROTO_UNWATCH <box_protocol-unwatch >`, and :ref: `IPROTO_EVENT <box_protocol-event >` commands.
942946
943947IPROTO_ID requests can be processed without authentication.
944948
949+ IPROTO_WATCH = 0x4a
950+ ~~~~~~~~~~~~~~~~~~~
951+
952+ See the :ref: `Watchers <box-protocol-watchers >` section below.
953+
954+ IPROTO_UNWATCH = 0x4b
955+ ~~~~~~~~~~~~~~~~~~~~~
956+
957+ See the :ref: `Watchers <box-protocol-watchers >` section below.
958+
959+ IPROTO_EVENT = 0x4c
960+ ~~~~~~~~~~~~~~~~~~~
961+
962+ See the :ref: `Watchers <box-protocol-watchers >` section below.
963+
964+
965+ .. _box-protocol-watchers :
966+
967+ Watchers
968+ --------
969+
970+ The commands below support asynchronous server-client notifications signalled
971+ with :ref: `box.broadcast() <box-broadcast >`.
972+ Servers that support the new feature set the ``IPROTO_FEATURE_WATCHERS `` feature in reply to the ``IPROTO_ID `` command.
973+ When the connection is closed, all watchers registered for it are unregistered.
974+
975+ The remote :ref: `watcher <box-watchers >` protocol works in the following way:
976+
977+ #. The client sends an ``IPROTO_WATCH `` packet to subscribe to the updates of a specified key defined on the server.
978+
979+ #. The server sends an ``IPROTO_EVENT `` packet to the subscribed client after registration.
980+ The packet contains the key name and its current value.
981+ After that, the packet is sent every time the key value is updated with
982+ ``box.broadcast() ``, provided that the last notification was acknowledged (see below).
983+
984+ #. After receiving the notification, the client sends an ``IPROTO_WATCH `` packet to acknowledge the notification.
985+
986+ #. If the client doesn't want to receive any more notifications, it unsubscribes by sending
987+ an ``IPROTO_UNWATCH `` packet.
988+
989+ All the three request types are asynchronous -- the receiving end doesn't send a packet in reply to any of them.
990+ Therefore, neither of them has a sync number.
991+
992+ .. _box_protocol-watch :
993+
994+ IPROTO_WATCH = 0x4a
995+ ~~~~~~~~~~~~~~~~~~~
996+
997+ Registers a new watcher for the given notification key or confirms a notification if the watcher is
998+ already subscribed.
999+ The watcher is notified after registration.
1000+ After that, the notification is sent every time the key is updated.
1001+ The server doesn't reply to the request unless it fails to parse the packet.
1002+
1003+ The body is a 2-item map:
1004+
1005+ .. cssclass :: highlight
1006+ .. parsed-literal ::
1007+
1008+ # <size>
1009+ msgpack(:samp: `{ {MP_UINT unsigned integer = size(<header>) + size(<body>) } } `)
1010+ # <header>
1011+ msgpack({
1012+ IPROTO_REQUEST_TYPE: IPROTO_WATCH
1013+ })
1014+ # <body>
1015+ msgpack({
1016+ IPROTO_EVENT_KEY: :samp: `{ {MP_STR string } }} `
1017+ })
1018+
1019+ ``IPROTO_EVENT_KEY `` (code 0x56) contains the key name.
1020+
1021+ .. _box_protocol-unwatch :
1022+
1023+ IPROTO_UNWATCH = 0x4b
1024+ ~~~~~~~~~~~~~~~~~~~~~
1025+
1026+ Unregisters a watcher subscribed to the given notification key.
1027+ The server doesn't reply to the request unless it fails to parse the packet.
1028+
1029+ The body is a 2-item map:
1030+
1031+ .. cssclass :: highlight
1032+ .. parsed-literal ::
1033+
1034+ # <size>
1035+ msgpack(:samp: `{ {MP_UINT unsigned integer = size(<header>) + size(<body>) } } `)
1036+ # <header>
1037+ msgpack({
1038+ IPROTO_REQUEST_TYPE: IPROTO_UNWATCH
1039+ })
1040+ # <body>
1041+ msgpack({
1042+ IPROTO_EVENT_KEY: :samp: `{ {MP_STR string } }} `
1043+ })
1044+
1045+ ``IPROTO_EVENT_KEY `` (code 0x56) contains a key name.
1046+
1047+ .. _box_protocol-event :
1048+
1049+ IPROTO_EVENT = 0x4c
1050+ ~~~~~~~~~~~~~~~~~~~
1051+
1052+ Sent by the server to notify a client about an update of a key.
1053+
1054+ The body is a 2-item map:
1055+
1056+ .. cssclass :: highlight
1057+ .. parsed-literal ::
1058+
1059+ # <size>
1060+ msgpack(:samp: `{ {MP_UINT unsigned integer = size(<header>) + size(<body>) } } `)
1061+ # <header>
1062+ msgpack({
1063+ IPROTO_REQUEST_TYPE: IPROTO_EVENT
1064+ })
1065+ # <body>
1066+ msgpack({
1067+ IPROTO_EVENT_KEY: :samp: `{ {MP_STR string } }} `,
1068+ IPROTO_EVENT_DATA: :samp: `{ {MP_OBJECT value } }} `
1069+ })
1070+
1071+ ``IPROTO_EVENT_KEY `` (code 0x56) contains the key name.
1072+
1073+ ``IPROTO_EVENT_DATA `` (code 0x57) contains data sent to a remote watcher.
1074+ The parameter is optional, the default value is ``nil ``.
9451075
9461076.. _box_protocol-responses :
9471077
0 commit comments