Клиентские протоколы WebSocket для Azure Web PubSub

Клиенты подключаются к Azure Web PubSub с помощью стандартного протокола WebSocket .

Конечные точки служб

Служба Web PubSub предоставляет два типа конечных точек для подключения клиентов:

  • /client/hubs/{hub}
  • /client/?hub={hub}

{hub} — обязательный параметр, который выступает в качестве изоляции для различных приложений. Его можно задать в пути или запросе.

Авторизация

Клиенты подключаются к службе с помощью веб-маркера JSON (JWT). Маркер может находиться в строке запроса, как /client/?hub={hub}&access_token={token}или в заголовкеAuthorization.Authorization: Bearer {token}

Ниже приведен общий рабочий процесс авторизации:

  1. Клиент ведет переговоры с сервером приложений. Сервер приложений содержит ПО промежуточного слоя авторизации, которое обрабатывает запрос клиента и подписывает JWT для клиента для подключения к службе.
  2. Сервер приложений возвращает JWT и URL-адрес службы клиенту.
  3. Клиент пытается подключиться к службе Web PubSub с помощью URL-адреса и маркера JWT, возвращенного с сервера приложений.

Поддерживаемые утверждения

При создании маркера доступа можно также настроить свойства для подключения клиента, указав специальные утверждения внутри маркера JWT:

Description Тип утверждения Значение утверждения Примечания.
Подключение userId клиента sub идентификатор пользователя Допускается только одно sub утверждение.
Время существования маркера exp время окончания срока действия Утверждение exp (время окончания срока действия) определяет время окончания срока действия или после чего маркер НЕ должен приниматься для обработки.
Разрешения, изначально связанные с подключением клиента role значение роли, определенное в разрешениях Укажите несколько утверждений, если у клиента есть несколько role разрешений.
Начальные группы, присоединенные к клиентскому подключению после подключения к Azure Web PubSub group группа для присоединения Укажите несколько group утверждений, если клиент присоединяется к нескольким группам.

Вы также можете добавить пользовательские утверждения в маркер доступа, и эти значения сохраняются в качестве claims свойства в тексте запроса вышестоящий подключения.

Пакеты SDK сервера предоставляют API-интерфейсы для создания маркера доступа для клиентов.

Простой клиент WebSocket

Простой клиент WebSocket, как указывает именование, является простым подключением WebSocket. Он также может иметь собственный подпротокол.

Например, в JavaScript можно создать простой клиент WebSocket с помощью следующего кода:

// simple WebSocket client1
var client1 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1');

// simple WebSocket client2 with some custom subprotocol
var client2 = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'custom.subprotocol')

Клиент WebSocket PubSub

Клиент PubSub WebSocket — это клиент WebSocket, использующий подпротоколы, определенные службой Azure Web PubSub:

  • json.webpubsub.azure.v1
  • protobuf.webpubsub.azure.v1

С помощью подпротокола, поддерживаемого службой, клиентPubSub WebSocket может напрямую публиковать сообщения в группах при наличии разрешений.

Подпротокол json.webpubsub.azure.v1

Подробные сведения см . здесь для подпротокола JSON.

Создание клиента PubSub WebSocket

var pubsubClient = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.webpubsub.azure.v1');

Присоединение группы от клиента напрямую

let ackId = 0;
pubsubClient.send(    
    JSON.stringify({
        type: 'joinGroup',
        group: 'group1',
        ackId: ++ackId
    }));

Отправка сообщений в группу из клиента напрямую

let ackId = 0;
pubsubClient.send(    
    JSON.stringify({
        type: 'sendToGroup',
        group: 'group1',
        ackId: ++ackId,
        dataType: "json",
        data: {
            "hello": "world"
        }
    }));

Подпротокол protobuf.webpubsub.azure.v1

Буферы протокола (protobuf) — это нейтральный на языке, нейтральный от платформы, двоичный протокол, упрощающий отправку двоичных данных. Protobuf предоставляет средства для создания клиентов для многих языков, таких как Java, Python, Objective-C, C#и C++. Дополнительные сведения о protobuf.

Например, в JavaScript можно создать клиент PubSub WebSocket с подпротоколом protobuf с помощью следующего кода:

// PubSub WebSocket client
var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.webpubsub.azure.v1');

Подробные сведения см . здесь для подпротокола protobuf.

Ответ AckId и Ack

Клиент PubSub WebSocket поддерживает ackId свойство для joinGroupсообщений leaveGroupsendToGroup и event сообщений. При использовании при обработке ackIdзапроса можно получить сообщение об ошибке. Вы можете исключить ackId сценарии пожара и забыть. В статье описаны различия в поведении между указанием ackId или нет.

Поведение при отсутствии ackId указанного значения

Если ackId он не указан, он забудет. Даже при брокере сообщений нет способа получать уведомления.

Поведение при ackId указании

Идемпотентная публикация

ackId — это номер uint64 и должен быть уникальным в клиенте с тем же идентификатором подключения. Служба Web PubSub записывает ackId и сообщения с теми же сообщениями, что и то же ackId сообщение. Служба отказывается брокерировать одно и то же сообщение несколько раз, что полезно в повторных попытках, чтобы избежать повторяющихся сообщений. Например, если клиент отправляет сообщение с ackId=5 сообщением и не получает ответ на ack, ackId=5то клиент повторяет попытку и снова отправляет то же сообщение. В некоторых случаях сообщение уже брокером, и ответ ack теряется по какой-то причине. Служба отклоняет повторные попытки и реагирует на ответ на ошибку с Duplicate причиной.

Ответ Ack

Служба Web PubSub отправляет ответ ack для каждого запроса.ackId

Формат:

{
    "type": "ack",
    "ackId": 1, // The ack id for the request to ack
    "success": false, // true or false
    "error": {
        "name": "Forbidden|InternalServerError|Duplicate",
        "message": "<error_detail>"
    }
}
  • Связывает ackId запрос.

  • success — это логическое значение и указывает, успешно ли запрос обрабатывается службой. Если это falseтак, клиенты должны проверка error.

  • error существует только в том случае, если successfalse клиенты должны иметь другую логику для разных name. Предположим, что в будущем может быть больше типов name .

    • Forbidden: у клиента нет разрешения на запрос. Клиенту необходимо добавить соответствующие роли.
    • InternalServerError: в службе произошла некоторая внутренняя ошибка. Требуется повторная попытка.
    • Duplicate: сообщение с тем же ackId уже обработано службой.

Разрешения

Как вы, вероятно, заметили в предыдущем описании клиента PubSub WebSocket, клиент может публиковаться на других клиентах только в том случае, если это разрешено. Разрешения клиента можно предоставить при подключении или во время существования подключения.

Role Разрешение
Не указано Клиент может отправлять запросы событий.
webpubsub.joinLeaveGroup Клиент может присоединиться или оставить любую группу.
webpubsub.sendToGroup Клиент может публиковать сообщения в любой группе.
webpubsub.joinLeaveGroup.<group> Клиент может присоединиться или оставить группу <group>.
webpubsub.sendToGroup.<group> Клиент может публиковать сообщения в группе <group>.

Разрешение клиента можно предоставить несколькими способами:

1. Назначение роли клиенту при создании маркера доступа

Клиент может подключиться к службе с помощью маркера JWT. Полезные данные маркера могут содержать такие сведения, как role клиент. При подписи маркера JWT клиенту вы можете предоставить клиенту разрешения, предоставив определенным ролям клиента.

Например, давайте подписываем токен JWT, имеющий разрешение на отправку сообщений group1 и group2:

let token = await serviceClient.getClientAccessToken({
    roles: [ "webpubsub.sendToGroup.group1", "webpubsub.sendToGroup.group2" ]
});

2. Назначение роли клиенту с помощью обработчика connect событий

Роли клиентов также можно задать при connect регистрации обработчика событий, а обработчик событий вышестоящий может вернуть roles клиент в службу Web PubSub при обработке connect событий.

Например, в JavaScript можно настроить handleConnect событие для этого:

let handler = new WebPubSubEventHandler("hub1", {
  handleConnect: (req, res) => {
    // auth the connection and set the userId of the connection
    res.success({
      roles: [ "webpubsub.sendToGroup.group1", "webpubsub.sendToGroup.group2" ]
    });
  },
});

3. Назначение роли клиенту через REST API или пакеты SDK сервера во время выполнения

let service = new WebPubSubServiceClient("<your_connection_string>", "test-hub");
await service.grantPermission("<connection_id>", "joinLeaveGroup", { targetName: "group1" });

Следующие шаги

Используйте эти ресурсы для начала создания собственного приложения: