다음을 통해 공유


Azure Web PubSub 지원 protobuf WebSocket 하위 프로토콜

이 문서에서는 하위 프로토콜 protobuf.webpubsub.azure.v1을 설명합니다.

클라이언트에서 이 하위 프로토콜을 사용하는 경우 나가는 데이터 프레임과 들어오는 데이터 프레임은 모두 프로토콜 버퍼(protobuf) 페이로드여야 합니다.

개요

protobuf.webpubsub.azure.v1 하위 프로토콜을 사용하면 클라이언트에서 업스트림 서버로 왕복하는 대신 게시-구독(PubSub)을 직접 수행할 수 있습니다. protobuf.webpubsub.azure.v1 하위 프로토콜을 통한 WebSocket 연결을 PubSub WebSocket 클라이언트라고 합니다.

예를 들어 JavaScript에서 다음을 사용하여 protobuf 하위 프로토콜을 통해 PubSub WebSocket 클라이언트를 만들 수 있습니다.

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

간단한 WebSocket 클라이언트의 경우 서버에는 클라이언트의 이벤트를 처리하는 데 필요한 역할이 있습니다. 간단한 WebSocket 연결은 메시지를 보낼 때 항상 message 이벤트를 트리거하고, 항상 서버 쪽에서 메시지를 처리하고 다른 작업을 수행합니다. protobuf.webpubsub.azure.v1 하위 프로토콜을 사용하면 권한 있는 클라이언트에서 조인 요청을 사용하여 그룹에 조인하고 게시 요청을 직접 사용하여 메시지를 그룹에 게시할 수 있습니다. 또한 클라이언트에서 메시지가 속한 이벤트를 사용자 지정하기 위해 이벤트 요청을 사용하여 메시지를 다양한 업스트림 이벤트 처리기로 라우팅할 수 있습니다.

참고 항목

현재 Web PubSub 서비스는 proto3만 지원합니다.

사용 권한

PubSub WebSocket 클라이언트는 권한 부여된 경우에만 다른 클라이언트에 게시할 수 있습니다. 클라이언트에 할당된 roles는 클라이언트에 부여된 권한을 결정합니다.

역할 Permission
지정되지 않음 클라이언트는 이벤트 요청을 보낼 수 있습니다.
webpubsub.joinLeaveGroup 클라이언트는 모든 그룹에 가입/탈퇴할 수 있습니다.
webpubsub.sendToGroup 클라이언트는 모든 그룹에 메시지를 게시할 수 있습니다.
webpubsub.joinLeaveGroup.<group> 클라이언트는 <group> 그룹에 조인하거나 탈퇴할 수 있습니다.
webpubsub.sendToGroup.<group> 클라이언트는 <group> 그룹에 메시지를 게시할 수 있습니다.

서버는 REST API 또는 서버 SDK를 통해 클라이언트 권한을 동적으로 부여하거나 해지할 수 있습니다.

요청

모든 요청 메시지는 다음 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;
    }
}

그룹 가입

형식:

join_group_message.group을 그룹 이름으로 설정합니다.

  • ackId는 각 요청의 ID이며 고유해야 합니다. 서비스는 요청 처리 결과를 알리기 위해 ack 응답 메시지를 보냅니다. 자세한 내용은 AckId 및 Ack 응답에서 확인할 수 있습니다.

그룹 탈퇴

형식:

leave_group_message.group을 그룹 이름으로 설정합니다.

  • ackId는 각 요청의 ID이며 고유해야 합니다. 서비스는 요청 처리 결과를 알리기 위해 ack 응답 메시지를 보냅니다. 자세한 내용은 AckId 및 Ack 응답에서 확인할 수 있습니다.

메시지 게시

형식:

  • ackId: 각 요청의 고유 ID입니다. 서비스는 요청 처리 결과를 알리기 위해 ack 응답 메시지를 보냅니다. 자세한 내용은 AckId 및 Ack 응답에서 확인할 수 있습니다.

  • dataType: MessageDatadata에 따라 protobuf, text 또는 binary일 수 있는 데이터 형식입니다. 수신 클라이언트는 dataType를 사용하여 콘텐츠를 올바르게 처리할 수 있습니다.

  • protobuf: send_to_group_message.data.protobuf_data를 설정하면 암시적 dataTypeprotobuf입니다. protobuf_dataAny 메시지 유형일 수 있습니다. 다른 모든 클라이언트는 protobuf SDK에서 역직렬화할 수 있는 protobuf로 인코딩된 이진 파일을 받습니다. 텍스트 기반 콘텐츠(예: json.webpubsub.azure.v1)만 지원하는 클라이언트는 Base64로 인코딩된 이진 파일을 받습니다.

  • text: send_to_group_message.data.text_data를 설정하면 암시적 dataTypetext입니다. text_data는 문자열이어야 합니다. 다른 프로토콜을 사용하는 모든 클라이언트는 UTF-8로 인코딩된 문자열을 받습니다.

  • binary: send_to_group_message.data.binary_data를 설정하면 암시적 dataTypebinary입니다. binary_data는 바이트 배열이어야 합니다. 다른 프로토콜을 사용하는 모든 클라이언트는 protobuf 인코딩 없이 원시 이진 파일을 받습니다. 텍스트 기반 콘텐츠(예: json.webpubsub.azure.v1)만 지원하는 클라이언트는 Base64로 인코딩된 이진 파일을 받습니다.

사례 1: 텍스트 데이터 게시

send_to_group_message.groupgroup으로 설정하고, send_to_group_message.data.text_data"text data"으로 설정합니다.

  • group 그룹의 protobuf 하위 프로토콜 클라이언트는 이진 프레임을 받고, DownstreamMessage를 사용하여 역직렬화할 수 있습니다.

  • group의 JSON 하위 프로토콜 클라이언트는 다음을 수신합니다.

    {
        "type": "message",
        "from": "group",
        "group": "group",
        "dataType" : "text",
        "data" : "text data"
    }
    
  • group의 단순 WebSocket 클라이언트는 text data 문자열을 수신합니다.

사례 2: protobuf 데이터 게시

다음과 같은 사용자 지정 메시지가 있다고 가정해 보겠습니다.

message MyMessage {
    int32 value = 1;
}

send_to_group_message.groupgroup으로 설정하고, send_to_group_message.data.protobuf_datavalue = 1이 있는 Any.pack(MyMessage)로 설정합니다.

  • group의 protobuf 하위 프로토콜 클라이언트는 이진 프레임을 받고, DownstreamMessage를 사용하여 역직렬화할 수 있습니다.

  • group의 하위 프로토콜 클라이언트는 다음을 받습니다.

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

    참고 항목

    데이터는 Base64로 인코딩되고 역직렬화 가능한 protobuf 이진 파일입니다.

다음 protobuf 정의를 사용하고, Any.unpack()을 사용하여 역직렬화할 수 있습니다.

syntax = "proto3";

message MyMessage {
    int32 value = 1;
}
  • group의 단순 WebSocket 클라이언트는 이진 프레임을 수신합니다.

    # 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
    

사례 3: 이진 데이터 게시

send_to_group_message.groupgroup으로 설정하고, send_to_group_message.data.binary_data[1, 2, 3]으로 설정합니다.

  • group 그룹의 protobuf 하위 프로토콜 클라이언트는 이진 프레임을 받고, DownstreamMessage를 사용하여 역직렬화할 수 있습니다.

  • group 그룹의 JSON 하위 프로토콜 클라이언트는 다음을 받습니다.

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

    JSON 하위 프로토콜 클라이언트는 텍스트 기반 메시징만 지원하므로 이진 파일은 항상 Base64로 인코딩됩니다.

  • group의 단순 WebSocket 클라이언트는 이진 파일 프레임에서 이진 데이터를 수신합니다.

    # Show in hexadecimal
    01 02 03
    

사용자 지정 이벤트 보내기

암시적 dataType이 있습니다. 이는 설정한 dataType에 따라 protobuf, text 또는 binary일 수 있습니다. 수신기 클라이언트는 dataType을 사용하여 콘텐츠를 올바르게 처리할 수 있습니다.

  • protobuf: event_message.data.protobuf_data를 설정하면 암시적 dataTypeprotobuf입니다. protobuf_data 값은 지원되는 protobuf 형식일 수 있습니다. 이벤트 처리기는 모든 protobuf SDK에서 역직렬화할 수 있는 protobuf로 인코딩된 이진 파일을 받습니다.

  • text: event_message.data.text_data를 설정하면 암시적 dataTypetext입니다. text_data 값은 시간 간격의 문자열이어야 합니다. 이벤트 처리기는 UTF-8로 인코딩된 문자열을 받습니다.

  • binary: event_message.data.binary_data를 설정하면 암시적 dataTypebinary입니다. binary_data 값은 시간 간격의 바이트 배열이어야 합니다. 이벤트 처리기는 원시 이진 프레임을 받습니다.

사례 1: 텍스트 데이터를 사용하여 이벤트 보내기

event_message.data.text_data"text data"로 설정합니다.

업스트림 이벤트 처리기는 다음과 비슷한 요청을 받습니다.

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

CloudEvents HTTP 요청의 Content-TypedataType=text인 경우 text/plain입니다.

사례 2: protobuf 데이터를 사용하여 이벤트 보내기

다음 고객 메시지를 받았다고 가정합니다.

message MyMessage {
    int32 value = 1;
}

event_message.data.protobuf_datavalue = 1이 있는 any.pack(MyMessage)를 설정합니다.

업스트림 이벤트 처리기는 다음과 비슷한 요청을 받습니다.

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

CloudEvents HTTP 요청의 Content-TypedataType=protobuf인 경우 application/x-protobuf입니다.

데이터는 유효한 protobuf 이진 파일입니다. 다음 protoany.unpack()을 사용하여 역직렬화할 수 있습니다.

syntax = "proto3";

message MyMessage {
    int32 value = 1;
}

사례 3: 이진 데이터를 사용하여 이벤트 보내기

send_to_group_message.binary_data[1, 2, 3]로 설정합니다.

업스트림 이벤트 처리기는 다음과 비슷한 요청을 받습니다.

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 

dataType=binary의 경우 CloudEvents HTTP 요청의 Content-Typeapplication/octet-stream입니다. WebSocket 프레임은 텍스트 메시지 프레임의 경우 text 형식이거나 binary 메시지 프레임의 경우 UTF-8로 인코딩된 이진 프레임일 수 있습니다.

메시지가 미리 지정된 형식과 일치하지 않으면 서비스에서 클라이언트를 거부합니다.

응답

모든 응답 메시지는 다음 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;
        }
    }
}

클라이언트에서 받은 메시지는 ack, message 또는 system의 세 가지 형식 중 하나일 수 있습니다.

ack 응답

요청에 ackId가 포함되면 서비스에서 이 요청에 대한 ack 응답을 반환합니다. 클라이언트 구현은 다음을 포함하여 이 ack 메커니즘을 처리해야 합니다.

  • asyncawait 작업에 대한 ack 응답을 기다립니다.
  • 특정 기간 동안 ack 응답을 받지 못한 경우 시간 제한 확인을 받습니다.

클라이언트 구현은 항상 먼저 확인하여 success 상태가 true 또는 false인지 확인해야 합니다. success 상태가 false이면 클라이언트는 error 속성에서 오류 세부 정보를 읽을 수 있습니다.

메시지 응답

클라이언트는 조인한 그룹에서 게시된 메시지를 받을 수 있습니다. 또는 서버에서 특정 클라이언트 또는 특정 사용자에게 메시지를 보낼 때 서버 관리 역할로부터 메시지를 받을 수 있습니다.

다음 시나리오에서는 항상 DownstreamMessage.DataMessage 메시지가 표시됩니다.

  • 메시지가 그룹에서 오는 경우 fromgroup입니다. 메시지가 서버에서 오는 경우 fromserver입니다.
  • 메시지가 그룹에서 오는 경우 group은 그룹 이름입니다.

발신기의 dataType은 다음 메시지 중 하나를 보냅니다.

  • dataTypetext인 경우 message_response_message.data.text_data를 사용합니다.
  • dataTypebinary인 경우 message_response_message.data.binary_data를 사용합니다.
  • dataTypeprotobuf인 경우 message_response_message.data.protobuf_data를 사용합니다.
  • dataTypejson인 경우 message_response_message.data.text_data를 사용하고, 콘텐츠는 직렬화된 JSON 문자열입니다.

시스템 응답

Web PubSub 서비스에서는 시스템 관련 응답을 클라이언트에 보낼 수도 있습니다.

연결됨

클라이언트에서 서비스에 연결하면 DownstreamMessage.SystemMessage.ConnectedMessage 메시지가 표시됩니다.

연결 끊김

서버에서 연결을 닫거나 서비스에서 클라이언트를 거부하면 DownstreamMessage.SystemMessage.DisconnectedMessage 메시지가 표시됩니다.

다음 단계

다음 리소스를 사용하여 사용자 고유의 애플리케이션 빌드를 시작합니다.