Skip to content

Commit b18ed10

Browse files
authored
Merge pull request #223247 from cebundy/wps-reliable-subprotocol
[Web PubSub]: Freshness review for howto-develop-reliable-clients
2 parents 0491cd2 + 2519fc0 commit b18ed10

File tree

1 file changed

+33
-21
lines changed

1 file changed

+33
-21
lines changed

articles/azure-web-pubsub/howto-develop-reliable-clients.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,43 @@ author: chenyl
55
ms.author: chenyl
66
ms.service: azure-web-pubsub
77
ms.topic: reference
8-
ms.date: 12/15/2021
8+
ms.date: 01/12/2023
99
---
1010

1111
# Create reliable Websocket with subprotocol
1212

13-
Websocket client connections may drop due to intermittent network issue and when connections drop, messages will also be lost. In a pubsub system, publishers are decoupled from subscribers, so publishers hard to detect subscribers' drop or message loss. It's crucial for clients to overcome intermittent network issue and keep the reliability of message delivery. To achieve that, you can create a reliable Websocket client with the help of reliable subprotocols.
13+
When Websocket client connections drop due to intermittent network issues, messages can be lost. In a pub/sub system, publishers are decoupled from subscribers, so publishers may not detect a subscribers' dropped connection or message loss. It's crucial for clients to overcome intermittent network issues and maintain reliable message delivery. To achieve that, you can create a reliable Websocket client with the help of reliable Azure Web PubSub subprotocols.
1414

1515
> [!NOTE]
16-
> Reliable protocols are still in preview. Some changes are expected in future.
16+
> Reliable protocols are still in preview. Some changes are expected in the future.
1717
1818
## Reliable Protocol
1919

20-
Service supports two reliable subprotocols `json.reliable.webpubsub.azure.v1` and `protobuf.reliable.webpubsub.azure.v1`. Clients must follow the protocol, mainly including the part of reconnection, publisher and subscriber to achieve the reliability, or the message delivery may not work as expected or the service may terminate the client as it violates the protocol spec.
20+
The Web PubSub service supports two reliable subprotocols `json.reliable.webpubsub.azure.v1` and `protobuf.reliable.webpubsub.azure.v1`. Clients must follow the publisher, subscriber, and reconnection parts of the subprotocol to achieve reliability. Failing to properly implement the subprotocol may result in the message delivery not working as expected or the service terminating the client due to protocol violations.
2121

2222
## Initialization
2323

24-
To use reliable subprotocols, you must set subprotocol when constructing Websocket connections. In JavaScript, you can use as following:
24+
To use reliable subprotocols, you must set the subprotocol when constructing Websocket connections. In JavaScript, you can use the following code:
25+
26+
- Use Json reliable subprotocol:
2527

26-
- Use Json reliable subprotocol
2728
```js
2829
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.reliable.webpubsub.azure.v1');
2930
```
3031

31-
- Use Protobuf reliable subprotocol
32+
- Use Protobuf reliable subprotocol:
33+
3234
```js
3335
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.reliable.webpubsub.azure.v1');
3436
```
3537

3638
## Reconnection
3739

38-
Websocket connections relay on TCP, so if the connection doesn't drop, all messages should be lossless and in order. When facing network issue and connections drop, all the status such as group and message info are kept by the service and wait for reconnection to recover. A Websocket connection owns a session in the service and the identifier is `connectionId`. Reconnection is the basis of achieving reliability and must be implemented. When a new connection connects to the service using reliable subprotocols, the connection will receive a `Connected` message contains `connectionId` and `reconnectionToken`.
40+
Reconnection is the basis of achieving reliability and must be implemented when using the `json.reliable.webpubsub.azure.v1` and `protobuf.reliable.webpubsub.azure.v1` protocols.
41+
42+
Websocket connections rely on TCP. When the connection doesn't drop, messages are lossless and delivered in order. To prevent message loss over dropped connections, the Web PubSub service retains the connection status information, including group and message information. This information is used to restore the client on reconnection
43+
44+
When the client reconnects to the service using reliable subprotocols, the client will receive a `Connected` message containing the `connectionId` and `reconnectionToken`. The `connectionId` identifies the session of the connection in the service.
3945
4046
```json
4147
{
@@ -46,21 +52,25 @@ Websocket connections relay on TCP, so if the connection doesn't drop, all messa
4652
}
4753
```
4854
49-
Once the WebSocket connection dropped, the client should first try to reconnect with the same `connectionId` to keep the session. Clients don't need to negotiate with server and obtain the `access_token`. Instead, reconnection should make a websocket connect request to service directly with `connection_id` and `reconnection_token` with the following uri:
55+
Once the WebSocket connection drops, the client should try to reconnect with the same `connectionId` to restore the same session. Clients don't need to negotiate with the server and obtain the `access_token`. Instead, on reconnection the client should make a WebSocket connect request directly to the service with the service host name, `connection_id`, and `reconnection_token`:
5056

51-
```
57+
```text
5258
wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connection_id>&awps_reconnection_token=<reconnection_token>
5359
```
5460

55-
Reconnection may fail as network issue hasn't been recovered yet. Client should keep retrying reconnecting until
56-
1. Websocket connection closed with status code 1008. The status code means the connectionId has been removed from the service.
57-
2. Reconnection failure keeps more than 1 minute.
61+
Reconnection may fail if the network issue hasn't been recovered yet. The client should keep retrying to reconnect until:
62+
63+
1. The Websocket connection is closed with status code 1008. The status code means the connectionId has been removed from the service.
64+
2. A reconnection failure continues to occur for more than 1 minute.
5865
5966
## Publisher
6067
61-
Clients who send events to event handler or publish message to other clients are called publishers in the document. Publishers should set `ackId` to the message to get acknowledged from the service about whether the message publishing success or not. The `ackId` in message is the identifier of the message, which means different messages should use different `ackId`s, while resending message should keep the same `ackId` for the service to de-duplicate.
68+
Clients that send events to event handlers or publish messages to other clients are called publishers. Publishers should set `ackId` in the message to receive an acknowledgment from the Web PubSub service that publishing the message was successful or not.
69+
70+
The `ackId` is the identifier of the message, each new message should use a unique ID. The original `ackId` should be used when resending a message.
6271
6372
A sample group send message:
73+
6474
```json
6575
{
6676
"type": "sendToGroup",
@@ -72,6 +82,7 @@ A sample group send message:
7282
```
7383
7484
A sample ack response:
85+
7586
```json
7687
{
7788
"type": "ack",
@@ -80,10 +91,10 @@ A sample ack response:
8091
}
8192
```
8293
83-
If the service returns ack with `success: true`, the message has been processed by the service and the client can expect the message will be delivered to all subscribers.
94+
When the Web PubSub service returns an ack response with `success: true`, the message has been processed by the service, and the client can expect the message will be delivered to all subscribers.
95+
96+
When the service experiences a transient internal error and the message can't be sent to subscriber, the publisher will receive an ack with `success: false`. The publisher should read the error to determine whether or not to resend the message. If the message is resent, the same `ackId` should be used.
8497

85-
However, In some cases, Service meets some transient internal error and the message can't be sent to subscriber. In such case, publisher will receive an ack like following and should resend message with the same `ackId` if it's necessary based on business logic.
86-
8798
```json
8899
{
89100
"type": "ack",
@@ -98,7 +109,7 @@ However, In some cases, Service meets some transient internal error and the mess
98109

99110
![Message Failure](./media/howto-develop-reliable-clients/message-failed.png)
100111

101-
Service's ack may be dropped because of WebSockets connection dropped. So, publishers should get notified when Websocket connection drops and resend message with the same `ackId` after reconnection. If the message has actually processed by the service, it will response ack with `Duplicate` and publishers should stop resending this message again.
112+
If the service's ack response is lost because the WebSocket connection dropped, the publisher should resend the message with the same `ackId` after reconnection. When the message was previously processed by the service, it will send an ack containing a `Duplicate` error. The publisher should stop resending this message.
102113
103114
```json
104115
{
@@ -116,16 +127,17 @@ Service's ack may be dropped because of WebSockets connection dropped. So, publi
116127
117128
## Subscriber
118129
119-
Clients who receive messages sent from event handlers or publishers are called subscriber in the document. When connections drop by network issues, the service doesn't know how many messages are actually sent to subscribers. So subscribers should tell the service which message has been received. Data Messages contains `sequenceId` and subscribers must ack the sequence-id with sequence ack message:
130+
Clients that receive messages from event handlers or publishers are called subscribers. When connections drop due to network issues, the Web PubSub service doesn't know how many messages were sent to subscribers. To determine the last message received by the subscriber, the service sends a data message containing a `sequenceId`. The subscriber responds with a sequence ack message:
120131

121132
A sample sequence ack:
133+
122134
```json
123135
{
124136
"type": "sequenceAck",
125137
"sequenceId": 1
126138
}
127139
```
128140

129-
The sequence-id is a uint64 incremental number with-in a connection-id session. Subscribers should record the largest sequence-id it ever received and accept all messages with larger sequence-id and drop all messages with smaller or equal sequence-id. The sequence ack supports cumulative ack, which means if you ack `sequence-id=5`, the service will treat all messages with sequence-id smaller than 5 have already been received by subscribers. Subscribers should ack with the largest sequence-id it recorded, so that the service can skip redelivering messages that subscribers have already received.
141+
The `sequenceId` is a uint64 incremental number in a connection-id session. Subscribers should record the largest `sequenceId` it has received, accept only messages with a larger `sequenceId`, and drop messages with a smaller or equal `sequenceId`. The subscriber should ack with the largest `sequenceId` it recorded, so that the service can skip redelivering messages that subscribers have already received. For example, if the subscriber responds with a `sequenceAck` with `sequenceId: 5`, the service will only resend messages with a `sequenceId` larger than 5.
130142

131-
All messages are delivered to subscribers in order until the WebSockets connection drops. With sequence-id, the service can have the knowledge about how many messages subscribers have actually received across WebSockets connections with-in a connection-id session. After a WebSockets connection drop, the service will redeliver messages it should deliver but not ack-ed by the subscriber. The service hold messages that are not ack-ed with limit, if messages exceed the limit, the service will close the WebSockets connection and remove the connection-id session. Thus, subscribers should ack the sequence-id as soon as possible.
143+
All messages are delivered to subscribers in order until the WebSocket connection drops. With `sequenceId`, the service can know how many messages subscribers have received across WebSocket connections in a session. After a WebSocket connection drops, the service will redeliver messages not acknowledged by the subscriber. The service stores a limited number of unacknowledged messages. When the number of messages exceed the limit, the service will close the WebSocket connection and remove the session. Thus, subscribers should ack the `sequenceId` as soon as possible.

0 commit comments

Comments
 (0)