github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/docs/source/rest_api/state_delta_websockets.rst (about) 1 ***************************************** 2 State Delta Subscriptions via Web Sockets 3 ***************************************** 4 5 As transactions are committed to the blockchain, an app developer may be 6 interested in receiving events related to the changes in state that result. 7 These events, `StateDeltaEvents`, include information about the advance of the 8 blockchain, as well as state changes that can be limited to specific address 9 spaces in the global state. 10 11 An application can subscribe to receive these events via a web socket, provided 12 by the REST API component. For example, a single-page JavaScript application may 13 open a web socket connection and subscribe to a particular transaction family's 14 state values, using the incoming events to re-render portions of the display. 15 16 .. note:: 17 18 All examples here are written in JavaScript, and assumes the Sawtooth REST 19 API is reachable at `localhost`. 20 21 Opening a Web Socket 22 ==================== 23 24 The application developer must first open a web socket. This is accomplished 25 by using standard means. In the case of in-browser JavaScript: 26 27 .. code-block:: javascript 28 29 let ws = new WebSocket('ws:localhost:8008/subscriptions') 30 31 If the REST API is running, it should trigger an event on the web socket's 32 `onopen` handler. 33 34 Subscribing to State Changes 35 ============================ 36 37 In order to subscribe to an address space in the global state, first a message 38 needs to be sent on the socket with the list of prefixes. It is a best-practice 39 to send this message as part of the web socket's `onopen` handler. 40 41 In the following example, we'll subscribe to changes in the XO family: 42 43 .. code-block:: javascript 44 45 ws.onopen = () => { 46 ws.send(JSON.stringify({ 47 'action': 'subscribe', 48 'address_prefixes': ['5b7349'] 49 })) 50 } 51 52 This message will begin the subscription of events as of the current block. If 53 you are interested in the state prior to the point of subscription, you should 54 fetch the values of state via the REST API's `/state` endpoint. 55 56 Subscriptions may be changed by sending a subscribe message at later time while 57 the websocket is open. It is up to the client to maintain the list of address 58 prefixes of interest. Any subsequent subscriptions will overwrite this list. 59 60 61 Events 62 ====== 63 64 Once subscribed, events will be received via the web socket's `onmessage` 65 handler. The event data is a JSON string, which looks like the following: 66 67 .. code-block:: javascript 68 69 { 70 "block_num": 8, 71 "block_id": "ab7cbc7a...", 72 "previous_block_id": "d4b46c1c...", 73 "state_changes": [ 74 { 75 "type": "SET", 76 "value": "oWZQdmxqcmsZU4w"=, 77 "address": "1cf126613a..." 78 }, 79 ... 80 ] 81 } 82 83 There is an entry in the `state_changes` array for each address that matches the 84 `address_prefixes` provided during the subscribe action. The type is either 85 "SET" or "DELETE". In the case of "SET" the value is base-64 encoded (like the 86 `/state` endpoint's response). In the case of "DELETE", only the address is 87 provided. If you are using a transaction family that supports deletes, you'll 88 need to keep track of values via address, as well. 89 90 Missed Events 91 ------------- 92 93 In the case where you have missed an event, a request can be sent via the web 94 socket for a particular block's changes. You can use the `previous_block_id` 95 from the current event to request the previous block's events, for example. 96 Send the following message: 97 98 .. code-block:: javascript 99 100 ws.send(JSON.stringify({ 101 'action': 'get_block_deltas', 102 'block_id': 'd4b46c1c...', 103 'address_prefixes': ['5b7349'] 104 })) 105 106 The event will be returned in the same manner as any other event, so it is 107 recommended that you push the events on to a stack before processing them. 108 109 If the block id does not exist, the following error will be returned: 110 111 .. code-block:: javascript 112 113 { 114 "error": "Must specify a block id" 115 } 116 117 Unsubscribing 118 ============= 119 120 To unsubscribe, you can either close the web socket, or if you want to 121 unsubscribe temporarily, you can send an unsubscribe action: 122 123 .. code-block:: javascript 124 125 ws.send(JSON.stringify({ 126 'action': 'unsubscribe' 127 })) 128 129 130 Errors and Warnings 131 =================== 132 133 An open, subscribed web socket may receive the following errors and warnings: 134 135 * the validator is unavailable 136 * an unknown action was requested 137 138 If the validator is unavailable to the REST API process, a warning will be sent 139 in lieu of a state delta event: 140 141 .. code-block:: javascript 142 143 { 144 "warning": "Validator unavailable" 145 } 146 147 If an unrecognized action is sent on to the server via the websocket, an error 148 message will be sent back: 149 150 .. code-block:: javascript 151 152 { 153 "error": "Unknown action \"bad_action\"" 154 } 155 156 157 .. Licensed under Creative Commons Attribution 4.0 International License 158 .. https://creativecommons.org/licenses/by/4.0/