Udostępnij za pośrednictwem


Podprotocol protokołu Web PubSub obsługiwane przez usługę Azure WebSocket protobuf

W tym dokumencie opisano podprotocol protobuf.webpubsub.azure.v1.

Gdy klient korzysta z tego podprotokolu, zarówno ramki danych wychodzących, jak i przychodzących powinny być ładunkami protokołu (protobuf).

Omówienie

Podprotocol protobuf.webpubsub.azure.v1 umożliwia klientowi bezpośrednie wykonywanie subskrypcji publikowania (PubSub) zamiast rundy na serwerze nadrzędnym. Połączenie protokołu WebSocket z protobuf.webpubsub.azure.v1 podprotokolem jest nazywane klientem protokołu WebSocket PubSub.

Na przykład w języku JavaScript można utworzyć klienta protokołu WebSocket PubSub za pomocą podprotocol protobuf za pomocą polecenia:

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

W przypadku prostego klienta protokołu WebSocket serwer ma niezbędną rolę obsługi zdarzeń od klientów. Proste połączenie protokołu WebSocket zawsze wyzwala message zdarzenie podczas wysyłania komunikatów i zawsze opiera się na stronie serwera w celu przetwarzania komunikatów i wykonywania innych operacji. Za pomocą protobuf.webpubsub.azure.v1 podprotocol autoryzowanego klienta może dołączyć do grupy przy użyciu żądań sprzężenia i publikowania komunikatów w grupie przy użyciu żądań publikowania bezpośrednio. Klient może również kierować komunikaty do różnych programów obsługi zdarzeń nadrzędnych przy użyciu żądań zdarzeń w celu dostosowania zdarzenia , do którego należy komunikat.

Uwaga

Obecnie usługa Web PubSub obsługuje tylko proto3.

Uprawnienia

Klient protokołu WebSocket PubSub może publikować tylko na innych klientach, gdy jest autoryzowany. Przypisany roles do klienta określ uprawnienia przyznane klientowi:

Rola Uprawnienie
Nieokreślona Klient może wysyłać żądania zdarzeń.
webpubsub.joinLeaveGroup Klient może dołączyć/pozostawić dowolną grupę.
webpubsub.sendToGroup Klient może publikować komunikaty w dowolnej grupie.
webpubsub.joinLeaveGroup.<group> Klient może dołączyć/opuścić grupę <group>.
webpubsub.sendToGroup.<group> Klient może publikować komunikaty w grupie <group>.

Serwer może dynamicznie udzielać lub odwoływać uprawnienia klienta za pośrednictwem interfejsów API REST lub zestawów SDK serwera.

Żądania

Wszystkie komunikaty żądań są zgodne z następującym formatem protobuf:

syntax = "proto3";

import "google/protobuf/any.proto";

message UpstreamMessage {
    oneof message {
        SendToGroupMessage send_to_group_message = 1;
        EventMessage event_message = 5;
        JoinGroupMessage join_group_message = 6;
        LeaveGroupMessage leave_group_message = 7;
    }

    message SendToGroupMessage {
        string group = 1;
        optional uint64 ack_id = 2;
        MessageData data = 3;
    }

    message EventMessage {
        string event = 1;
        MessageData data = 2;
        optional uint64 ack_id = 3;
    }
    
    message JoinGroupMessage {
        string group = 1;
        optional uint64 ack_id = 2;
    }

    message LeaveGroupMessage {
        string group = 1;
        optional uint64 ack_id = 2;
    }
}

message MessageData {
    oneof data {
        string text_data = 1;
        bytes binary_data = 2;
        google.protobuf.Any protobuf_data = 3;
    }
}

Dołączanie grup

Format:

Ustaw join_group_message.group nazwę grupy.

  • ackId to tożsamość każdego żądania i powinna być unikatowa. Usługa wysyła komunikat odpowiedzi ack, aby powiadomić wynik procesu żądania. Więcej szczegółów można znaleźć na stronie AckId i Ack Response

Pozostaw grupy

Format:

Ustaw leave_group_message.group nazwę grupy.

  • ackId to tożsamość każdego żądania i powinna być unikatowa. Usługa wysyła komunikat odpowiedzi ack, aby powiadomić wynik procesu żądania. Więcej szczegółów można znaleźć na stronie AckId i Ack Response

Publikowanie komunikatów

Format:

  • ackId: unikatowa tożsamość każdego żądania. Usługa wysyła komunikat odpowiedzi ack, aby powiadomić wynik procesu żądania. Więcej szczegółów można znaleźć na stronie AckId i Ack Response

  • dataType: format danych, który może mieć protobufwartość , textlub binary w zależności od data wartości w pliku MessageData. Klienci odbierający mogą używać dataType do poprawnego przetwarzania zawartości.

  • protobuf: Po ustawieniu send_to_group_message.data.protobuf_dataparametru niejawny dataType to protobuf. protobuf_datamoże mieć wartość Dowolny typ komunikatu. Wszyscy inni klienci otrzymują kodowany protobuf binarny, który może być deserializowany przez zestaw SDK protobuf. Klienci, którzy obsługują tylko zawartość tekstową (na przykład json.webpubsub.azure.v1), otrzymują plik binarny zakodowany w formacie Base64.

  • text: Po ustawieniu send_to_group_message.data.text_dataparametru niejawny dataType to text. text_data powinien być ciągiem. Wszyscy klienci z innymi protokołami otrzymują ciąg zakodowany w formacie UTF-8.

  • binary: Po ustawieniu send_to_group_message.data.binary_dataparametru niejawny dataType to binary. binary_data powinna być tablicą bajtów. Wszyscy klienci z innymi protokołami otrzymują nieprzetworzone dane binarne bez kodowania protobuf. Klienci, którzy obsługują tylko zawartość tekstową (na przykład json.webpubsub.azure.v1), otrzymują plik binarny zakodowany w formacie Base64.

Przypadek 1. Publikowanie danych tekstowych

Ustaw send_to_group_message.group wartość groupna , i ustaw wartość send_to_group_message.data.text_data "text data".

  • Klient podrzędny protobuf w grupie group odbiera ramkę binarną i może użyć parametru DownstreamMessage do deserializacji.

  • Klienci podrzędni JSON odbierają group :

    {
        "type": "message",
        "from": "group",
        "group": "group",
        "dataType" : "text",
        "data" : "text data"
    }
    
  • Prosti klienci protokołu WebSocket w group ciągu text dataodbierania .

Przypadek 2. Publikowanie danych protobuf

Załóżmy, że masz niestandardowy komunikat:

message MyMessage {
    int32 value = 1;
}

Ustaw send_to_group_message.group wartość na group i send_to_group_message.data.protobuf_data na Any.pack(MyMessage) wartość z wartością value = 1.

  • Klienci podrzędni protobuf w group odbieraniu ramki binarnej i mogą używać parametru DownstreamMessage do deserializacji.

  • Klient subprotocol w programie group odbiera:

    {
        "type": "message",
        "from": "group",
        "group": "G",
        "dataType" : "protobuf",
        "data" : "Ci90eXBlLmdvb2dsZWFwaXMuY29tL2F6dXJlLndlYnB1YnN1Yi5UZXN0TWVzc2FnZRICCAE=" // Base64-encoded bytes
    }
    

    Uwaga

    Dane są plikami binarnymi protobuf zakodowanymi w formacie Base64.

Możesz użyć następującej definicji protobuf i użyć Any.unpack() jej do deserializacji:

syntax = "proto3";

message MyMessage {
    int32 value = 1;
}
  • Prosti klienci protokołu WebSocket odbierają group ramkę binarną:

    # Show in hexadecimal
    0A 2F 74 79 70 65 2E 67 6F 6F 67 6C 65 61 70 69 73 2E 63 6F 6D 2F 61 7A 75 72 65 2E 77 65 62 70 75 62 73 75 62 2E 54 65 73 74 4D 65 73 73 61 67 65 12 02 08 01
    

Przypadek 3. Publikowanie danych binarnych

Ustaw send_to_group_message.group wartość groupna , i ustaw wartość send_to_group_message.data.binary_data [1, 2, 3].

  • Klient podrzędny protobuf w grupie group odbiera ramkę binarną i może użyć parametru DownstreamMessage do deserializacji.

  • Klient podrzędny JSON w grupie group otrzymuje:

    {
        "type": "message",
        "from": "group",
        "group": "group",
        "dataType" : "binary",
        "data" : "AQID", // Base64-encoded [1,2,3]
    }
    

    Ponieważ klient podrzędny JSON obsługuje tylko komunikaty tekstowe, plik binarny jest zawsze zakodowany w formacie Base64.

  • Prosti klienci protokołu WebSocket odbierają group dane binarne w ramce binarnej:

    # Show in hexadecimal
    01 02 03
    

Wysyłanie zdarzeń niestandardowych

Istnieje niejawny dataTypeelement , który może mieć protobufwartość , textlub binary, w zależności od ustawionego dataType ustawienia. Klienci odbiorcy mogą używać dataType do poprawnego obsługi zawartości.

  • protobuf: Po ustawieniu event_message.data.protobuf_dataparametru niejawny dataType to protobuf. Wartość protobuf_data może być dowolnym obsługiwanym typem protobuf. Procedura obsługi zdarzeń odbiera kodowany plik binarny protobuf, który może być deserializowany przez dowolny zestaw SDK protobuf.

  • text: Po ustawieniu event_message.data.text_dataparametru niejawny dataType to text. Wartość text_data powinna być ciągiem. Procedura obsługi zdarzeń odbiera ciąg zakodowany w formacie UTF-8.

  • binary: Po ustawieniu event_message.data.binary_dataparametru niejawny dataType to binary. Wartość binary_data powinna być tablicą bajtów. Procedura obsługi zdarzeń odbiera nieprzetworzonej ramki binarnej.

Przypadek 1. Wysyłanie zdarzenia z danymi tekstowymi

Ustaw wartość opcji event_message.data.text_data na "text data".

Program obsługi zdarzeń nadrzędnych odbiera żądanie podobne do:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: text/plain
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>

text data

Dla Content-Type żądania HTTP CloudEvents to text/plain, gdzie=dataTypetext .

Przypadek 2. Wysyłanie zdarzenia z danymi protobuf

Załóżmy, że otrzymano następujący komunikat klienta:

message MyMessage {
    int32 value = 1;
}

Ustaw event_message.data.protobuf_data na z any.pack(MyMessage)value = 1

Program obsługi zdarzeń nadrzędnych odbiera żądanie podobne do następującego:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/json
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>

// Just show in hexadecimal; read it as binary
0A 2F 74 79 70 65 2E 67 6F 6F 67 6C 65 61 70 69 73 2E 63 6F 6D 2F 61 7A 75 72 65 2E 77 65 62 70 75 62 73 75 62 2E 54 65 73 74 4D 65 73 73 61 67 65 12 02 08 01

Dla Content-Type żądania HTTP CloudEvents to application/x-protobuf, gdzie=dataTypeprotobuf .

Dane są prawidłowym plikiem binarnym protobuf. Możesz użyć następującego proto polecenia i any.unpack() wykonać deserializowanie go:

syntax = "proto3";

message MyMessage {
    int32 value = 1;
}

Przypadek 3. Wysyłanie zdarzenia z danymi binarnymi

Ustaw wartość opcji send_to_group_message.binary_data na [1, 2, 3].

Program obsługi zdarzeń nadrzędnych odbiera żądanie podobne do:

POST /upstream HTTP/1.1
Host: xxxxxx
WebHook-Request-Origin: xxx.webpubsub.azure.com
Content-Type: application/octet-stream
Content-Length: nnnn
ce-specversion: 1.0
ce-type: azure.webpubsub.user.<event_name>
ce-source: /client/{connectionId}
ce-id: {eventId}
ce-time: 2021-01-01T00:00:00Z
ce-signature: sha256={connection-id-hash-primary},sha256={connection-id-hash-secondary}
ce-userId: {userId}
ce-connectionId: {connectionId}
ce-hub: {hub_name}
ce-eventName: <event_name>

// Just show in hexadecimal; you need to read it as binary
01 02 03 

W przypadku dataType=binaryelementu dla Content-Type żądania HTTP CloudEvents to .application/octet-stream Ramka Protokołu WebSocket może być w text formacie ramek wiadomości tekstowych lub plików binarnych zakodowanych w formacie UTF-8 dla binary ramek komunikatów.

Usługa odrzuca klienta, jeśli komunikat nie jest zgodny z określonym formatem.

Odpowiedzi

Wszystkie komunikaty odpowiedzi są zgodne z następującym formatem protobuf:

message DownstreamMessage {
    oneof message {
        AckMessage ack_message = 1;
        DataMessage data_message = 2;
        SystemMessage system_message = 3;
    }
    
    message AckMessage {
        uint64 ack_id = 1;
        bool success = 2;
        optional ErrorMessage error = 3;
    
        message ErrorMessage {
            string name = 1;
            string message = 2;
        }
    }

    message DataMessage {
        string from = 1;
        optional string group = 2;
        MessageData data = 3;
    }

    message SystemMessage {
        oneof message {
            ConnectedMessage connected_message = 1;
            DisconnectedMessage disconnected_message = 2;
        }
    
        message ConnectedMessage {
            string connection_id = 1;
            string user_id = 2;
        }

        message DisconnectedMessage {
            string reason = 2;
        }
    }
}

Komunikaty odbierane przez klienta mogą znajdować się w dowolnym z trzech typów: ack, messagelub system.

Odpowiedź Ack

Jeśli żądanie zawiera ackId, usługa zwraca odpowiedź ack dla tego żądania. Implementacja klienta powinna obsługiwać ten mechanizm ack, w tym:

  • Oczekiwanie na odpowiedź ack dla async await operacji.
  • Sprawdzanie limitu czasu, gdy odpowiedź ack nie jest odbierana w określonym okresie.

Implementacja klienta powinna zawsze najpierw sprawdzać, czy success stan to true , czy false. success Gdy stan to false, klient może odczytać z error właściwości , aby uzyskać szczegółowe informacje o błędzie.

Odpowiedź na komunikat

Klienci mogą odbierać komunikaty opublikowane z grupy, do których dołączył klient. Mogą też odbierać komunikaty z roli zarządzania serwerem, gdy serwer wysyła komunikaty do określonego klienta lub określonego użytkownika.

Zawsze będziesz otrzymywać DownstreamMessage.DataMessage komunikat w następujących scenariuszach:

  • Gdy komunikat pochodzi z grupy, from to group. Gdy komunikat pochodzi z serwera, from to server.
  • Gdy komunikat pochodzi z grupy, group to nazwa grupy.

Nadawca dataType spowoduje wysłanie jednego z następujących komunikatów:

  • Jeśli dataType parametr ma wartość text, użyj polecenia message_response_message.data.text_data.
  • Jeśli dataType parametr ma wartość binary, użyj polecenia message_response_message.data.binary_data.
  • Jeśli dataType parametr ma wartość protobuf, użyj polecenia message_response_message.data.protobuf_data.
  • Jeśli dataType element to json, użyj elementu message_response_message.data.text_data, a zawartość jest serializowanym ciągiem JSON.

Odpowiedź systemu

Usługa Web PubSub może również wysyłać odpowiedzi związane z systemem do klienta.

Połączono

Gdy klient nawiązuje połączenie z usługą DownstreamMessage.SystemMessage.ConnectedMessage , zostanie wyświetlony komunikat.

Odłączony

Gdy serwer zamknie połączenie lub usługa odrzuci klienta, zostanie wyświetlony DownstreamMessage.SystemMessage.DisconnectedMessage komunikat.

Następne kroki

Użyj tych zasobów, aby rozpocząć tworzenie własnej aplikacji: