シグナリングの型定義

この章ではシグナリングの型について説明します。 シグナリングの仕様については シグナリング を参照ください。

型の表記は TypeScript で記述します。

基本的なデータ型

JSON 値

type JSON

JSON 値を表します。 仕様は RFC 8259 に従います。

デフォルト値

type Default<Type, Value> = Type

オブジェクトのプロパティの省略時のデフォルト値を表します。 例えば metadata?: Default<JSON, null> であれば、 metadata プロパティを省略すると、 JSON 型の null がデフォルト値として使われます。

長さに制限のある文字列

type LengthRestrictedString<Min, Max> = string

長さに制限のある文字列を表します。 長さの範囲は MixMax を含みます。 例えば LengthRestrictedString<1, 255> であれば、文字列の長さは 1 から 255 まで (255 を含む) です。

整数

type Int = number

整数です。 JSON に整数のみを表す値はないので、具体的な値は number の値です。

値の範囲が制限される整数

type RangedInt<Min, Max> = Int

値の範囲が制限される整数です。 値の範囲は MixMax を含みます。 例えば RangedInt<1, 5> であれば、有効な値は "1, 2, 3, 4, 5" のいずれかです。

ID

type ID = LengthRestrictedString<1, 255>

チャネル ID 、クライアント ID などに使われる値を表します。 長さが 1 から 255 の文字列です。

シグナリング

type Signaling =
    | ClientToServer
    | ServerToClient

type ClientToServer =
    | Connect
    | Answer
    | Candidate
    | UpdateToServer

type ServerToClient =
    | Offer
    | UpdateToClient
    | Push
    | Notify

シグナリングは「クライアントからサーバー (Sora) に送信される」メッセージと「サーバーからクライアントに送信される」メッセージに分かれます。

  • クライアントからサーバーに送信されるメッセージ

    • connect

    • answer

    • candidate

    • update

  • Server からクライアントに送信されるメッセージ

    • offer

    • update

    • push

    • notify

connect

type Connect = {
    type: "connect",
    role: Role,
    channel_id: ID,
    client_id?: ID,
    metadata?: JSON,
    signaling_notify_metadata?: JSON,
    multistream?: boolean,
    plan_b?: boolean,
    spotlight?: RangedInt<1, 5>,
    simulcast?: Default<Simulcast, false>,
    audio?: Default<Audio, true>,
    video?: Default<Video, true>,
    sdp?: String
}

ストリームの種別

type Role =
    | "upstream"
    | "downstream"

サイマルキャスト

type Simulcast =
    | boolean
    | { quality: "low" | "middle" | "high" }

音声

type Audio =
    | boolean
    | {
        codec_type: "OPUS" | "PCMU",
        bit_rate: RangedInt<6, 510>,
      }

映像

type Video =
    | boolean
    | {
        codec_type: "VP9" | "VP8" | "H264",
        bit_rate: RangedInt<1, 50000>,
      }

offer

type Offer = {
    type: "offer",
    sdp: string,
    client_id: ID,
    connection_id: ID,
    metadata?: Default<JSON, null>,
    config?: JSON
}

answer

type Answer = {
    type: "answer",
    sdp: string
}

candidate

type Candidate = {
    type: "candidate",
    candidate: string
}

update (サーバー -> クライアント)

type UpdateToClient = {
    type: "update",
    sdp: string
}

update (クライアント -> サーバー)

type UpdateToServer = {
    type: "update",
    sdp: string
}

push

type Push = {
    type: "push",
    data: object
}

notify

type Notify =
    | ConnectionCreated
    | ConnectionUpdated
    | ConnectionDestroyed
    | SpotlightChanged
    | NetworkStatus

connection.created

type ConnectionCreated = {
    type: "notify",
    event_type: "connection.created",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: object,
    metadata_list?: list<object>,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int
}

connection.updated

type ConnectionUpdated = {
    type: "notify",
    event_type: "connection.updated",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: object,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int
}

connection.destroyed

type ConnectionDestroyed = {
    type: "notify",
    event_type: "connection.destroyed",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: object,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int
}

spotlight.changed

type SpotlightChanged = {
    type: "notify",
    event_type: "spotlight.changed",
    client_id: ID | null,
    connection_id: ID | null,
    spotlight_id: ID,
    fixed?: boolean,
    audio: boolean,
    video: boolean
}

network.status

type NetworkStatus = {
    type: "notify",
    event_type: "network.status",
    unstable_level: RangedInt<0, 3>
}

完全な型定義

// デフォルト値のある型
type Default<Type, Value> = Type

// 長さに制限のある文字列
type LengthRestrictedString<Min, Max> = string

// 整数
type Int = number

// 値の範囲が制限される整数
type RangedInt<Min, Max> = Int

// 長さ 1..255 の文字列
type ID = LengthRestrictedString<1, 255>

// シグナリング
type Signaling =
    | ClientToServer
    | ServerToClient

// クライアントからサーバーに送信されるメッセージ
type ClientToServer =
    | Connect
    | Answer
    | Candidate
    | UpdateToServer

// サーバーからクライアントに送信されるメッセージ
type ServerToClient =
    | Offer
    | UpdateToClient
    | Push
    | Notify

// type: "connect"
type Connect = {
    type: "connect",
    role: Role,
    channel_id: ID,
    client_id?: ID,
    metadata?: JSON,
    signaling_notify_metadata?: JSON,
    multistream?: boolean,
    plan_b?: boolean,
    spotlight?: RangedInt<1, 5>,
    simulcast?: Default<Simulcast, false>,
    audio?: Default<Audio, true>,
    video?: Default<Video, true>,
    sdp?: String
}

// ストリームの種別
type Role =
    | "upstream"
    | "downstream"

// サイマルキャスト
type Simulcast =
    | boolean
    | { quality: "low" | "middle" | "high" }

// 音声
type Audio =
    | boolean
    | {
        codec_type: "OPUS" | "PCMU",
        bit_rate: RangedInt<6, 510>,
      }

// 映像
type Video =
    | boolean
    | {
        codec_type: "VP9" | "VP8" | "H264",
        bit_rate: RangedInt<1, 50000>,
      }

// type: "offer"
type Offer = {
    type: "offer",
    sdp: string,
    client_id: ID,
    connection_id: ID,
    metadata?: Default<JSON, null>,
    config?: JSON
}

// type: "answer"
type Answer = {
    type: "answer",
    sdp: string
}

// type: "candidate"
type Candidate = {
    type: "candidate",
    candidate: string
}

// type: "update"
// サーバーからクライアントに送信される
type UpdateToClient = {
    type: "update",
    sdp: string
}

// type: "update"
// クライアントからサーバーに送信される
type UpdateToServer = {
    type: "update",
    sdp: string
}

// type: "push"
type Push = {
    type: "push",
    data: object
}

// type: "notify"
type Notify =
    | ConnectionCreated
    | ConnectionUpdated
    | ConnectionDestroyed
    | SpotlightChanged
    | NetworkStatus

// "connection.created",
type ConnectionCreated = {
    type: "notify",
    event_type: "connection.created",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: object,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int
}

// "connection.updated"
type ConnectionUpdated = {
    type: "notify",
    event_type: "connection.updated",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: object,
    metadata_list?: list<object>,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int
}

// "connection.destroyed"
type ConnectionDestroyed = {
    type: "notify",
    event_type: "connection.destroyed",
    role: Role,
    client_id?: ID,
    connection_id?: ID,
    audio?: boolean,
    video?: boolean,
    metadata?: object,
    minutes: Int,
    channel_connections: Int,
    channel_upstream_connections: Int,
    channel_downstream_connections: Int
}

// "spotlight.changed"
type SpotlightChanged = {
    type: "notify",
    event_type: "spotlight.changed",
    client_id: ID | null,
    connection_id: ID | null,
    spotlight_id: ID,
    fixed?: boolean,
    audio: boolean,
    video: boolean
}

// "network.status"
type NetworkStatus = {
    type: "notify",
    event_type: "network.status",
    unstable_level: RangedInt<0, 3>
}