RPC 機能

概要

RPC 機能は、 DataChannel 経由で JSON-RPC 2.0 による Sora の一部 HTTP API 呼び出しを行うための仕組みです。 Sora の RPC 機能については Sora のドキュメント RPC 機能 をご確認ください。

警告

この機能は実験的機能のため、正式版では仕様が変更される可能性があります。

設定

RPC 機能は DataChannel 経由のシグナリングが有効な場合に利用できます。

Sora Android SDK で DataChannel 経由のシグナリングを有効にするには、 SoraMediaChanneldataChannelSignalingtrue を設定します。

// DataChannel 経由のシグナリングを有効にして接続
val mediaChannel =
    SoraMediaChannel(
        context = this,
        signalingEndpoint = "wss://example.com/signaling",
        channelId = "sora",
        dataChannelSignaling = true,
        mediaOption = option,
        listener = channelListener,
    )

mediaChannel.connect()

利用可能なメソッドの確認

利用可能なメソッド一覧は onOfferMessage コールバックで OfferMessage.rpcMethods から取得します。

override fun onOfferMessage(
    mediaChannel: SoraMediaChannel,
    offer: OfferMessage,
) {
    // 利用可能な RPC メソッド一覧を確認
    val rpcMethodNames: List<String> = offer.rpcMethods ?: emptyList()
    // ["2025.2.0/RequestSimulcastRid", "2025.2.0/PutSignalingNotifyMetadataItem", ...]
}

注釈

利用可能なメソッドは Sora の認証ウェブフックから払い出されている必要があります。

RPC 機能を利用する

RPC 機能を利用するには SoraMediaChannel.rpc メソッドを使います。

RequestSimulcastRid の例

/**
 * RequestSimulcastRid を呼び出す RPC サンプルです。
 * kotlinx.serialization を使って params を JSON 文字列に変換します。
 * result は JSON 文字列なので decode して利用します。
 */
import android.util.Log
import jp.shiguredo.sora.sdk.channel.SoraMediaChannel
import jp.shiguredo.sora.sdk.channel.rpc.SoraRpcException
import jp.shiguredo.sora.sdk.channel.rpc.SoraRpcResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Serializable
data class RequestSimulcastRidParams(
    @SerialName("sender_connection_id")
    val senderConnectionId: String? = null,
    val rid: String,
)

@Serializable
data class RequestSimulcastRidResult(
    @SerialName("channel_id")
    val channelId: String,
    @SerialName("receiver_connection_id")
    val receiverConnectionId: String,
    @SerialName("sender_connection_id")
    val senderConnectionId: String? = null,
    val rid: String,
)

fun requestSimulcastRid(
    mediaChannel: SoraMediaChannel,
    scope: CoroutineScope,
) {
    scope.launch {
        try {
            val params =
                RequestSimulcastRidParams(
                    senderConnectionId = "SENDER_CONNECTION_ID",
                    rid = "r1",
                )
            val paramsJson = Json.encodeToString(params)

            val result =
                mediaChannel.rpc(
                    method = "2025.2.0/RequestSimulcastRid",
                    paramsJson = paramsJson,
                )

            when (result) {
                is SoraRpcResult.Success -> {
                    val response =
                        result.result?.let { Json.decodeFromString<RequestSimulcastRidResult>(it) }
                    Log.d("Sora", "RPC success: $response")
                }
                is SoraRpcResult.Error ->
                    Log.e("Sora", "RPC error: ${result.error.message}")
                null -> Unit
            }
        } catch (e: SoraRpcException) {
            Log.e("Sora", "RPC failed: ${e.message}", e)
        }
    }
}

PutSignalingNotifyMetadataItem の例

/**
 * PutSignalingNotifyMetadataItem を呼び出す RPC サンプルです。
 * kotlinx.serialization を使って params を JSON 文字列に変換します。
 */
import android.util.Log
import jp.shiguredo.sora.sdk.channel.SoraMediaChannel
import jp.shiguredo.sora.sdk.channel.rpc.SoraRpcException
import jp.shiguredo.sora.sdk.channel.rpc.SoraRpcResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Serializable
data class PutSignalingNotifyMetadataItemParams(
    val push: Boolean? = null,
    val key: String,
    val value: String,
)

fun putSignalingNotifyMetadataItem(
    mediaChannel: SoraMediaChannel,
    scope: CoroutineScope,
) {
    scope.launch {
        try {
            val params =
                PutSignalingNotifyMetadataItemParams(
                    push = true,
                    key = "example_key",
                    value = "example_value",
                )
            val paramsJson = Json.encodeToString(params)

            val result =
                mediaChannel.rpc(
                    method = "2025.2.0/PutSignalingNotifyMetadataItem",
                    paramsJson = paramsJson,
                )

            when (result) {
                is SoraRpcResult.Success ->
                    Log.d("Sora", "Metadata updated: ${result.result}")
                is SoraRpcResult.Error ->
                    Log.e("Sora", "Failed to update metadata: ${result.error.message}")
                null -> Unit
            }
        } catch (e: SoraRpcException) {
            Log.e("Sora", "RPC failed: ${e.message}", e)
        }
    }
}

MediaChannel.rpc のレスポンスが不要な場合

isNotificationRequesttrue に設定すると JSON-RPC 2.0 の Notification として送信されます。 この場合は Sora からレスポンスは返らず、戻り値は null になります。 Notification に関する詳細は https://www.jsonrpc.org/specification#notification をご確認ください。

/**
 * Notification として送信する RPC サンプルです。
 * レスポンスは返りません。
 */
import android.util.Log
import jp.shiguredo.sora.sdk.channel.SoraMediaChannel
import jp.shiguredo.sora.sdk.channel.rpc.SoraRpcException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Serializable
data class PutSignalingNotifyMetadataItemParams(
    val push: Boolean? = null,
    val key: String,
    val value: String,
)

fun sendRpcNotification(
    mediaChannel: SoraMediaChannel,
    scope: CoroutineScope,
) {
    scope.launch {
        try {
            val params =
                PutSignalingNotifyMetadataItemParams(
                    push = true,
                    key = "example_key",
                    value = "example_value",
                )
            val paramsJson = Json.encodeToString(params)

            // Notification としてリクエストする
            mediaChannel.rpc(
                method = "2025.2.0/PutSignalingNotifyMetadataItem",
                paramsJson = paramsJson,
                isNotificationRequest = true,
            )

            Log.d("Sora", "RPC notification sent")
        } catch (e: SoraRpcException) {
            Log.e("Sora", "RPC failed: ${e.message}", e)
        }
    }
}

SoraMediaChannel.rpc について

SoraMediaChannel.rpc は suspend 関数として実装されており、Kotlin Coroutines を利用して非同期に RPC リクエストを送信します。 RPC のパラメータとレスポンスは JSON 文字列として扱います。エンコード / デコードは利用者側で行う必要があります。

シグネチャ

suspend fun rpc(
    method: String,
    paramsJson: String?,
    isNotificationRequest: Boolean = false,
    timeoutMillis: Long = DEFAULT_RPC_TIMEOUT_MILLIS,
): SoraRpcResult?

パラメータ

  • method: RPC メソッド名 (例: 2025.2.0/RequestSimulcastRid)

  • paramsJson: RPC パラメータの JSON 文字列。null の場合は params を省略。不正な JSON の場合は SoraRpcErrorReason.PARSE_ERROR になります

  • isNotificationRequest: true の場合は Notification として送信し、レスポンスを待たない。デフォルトは false

  • timeoutMillis: レスポンス待機のタイムアウト時間 (ミリ秒)

戻り値

SoraRpcResult? を返します。 Notification の場合は null を返します。

  • SoraRpcResult.Success: リクエスト成功を表し Sora からのレスポンス JSON 文字列が含まれます

  • SoraRpcResult.Error: リクエスト失敗を表し Sora からの JSON-RPC エラーが含まれます(error.data は JSON 文字列)

  • null: Notification であるためレスポンスはありません

RPC を利用できない場合や送信に失敗した場合は SoraRpcException をスローします。 SoraRpcException.reason は以下のいずれかです。

  • NOT_AVAILABLE: RPC が有効ではない

  • DATA_CHANNEL_UNAVAILABLE: RPC 用 DataChannel が存在しない

  • DATA_CHANNEL_CLOSED: RPC 用 DataChannel が開いていない

  • PEER_UNAVAILABLE: PeerChannel が存在しない

  • SEND_FAILED: RPC メッセージの送信に失敗

  • TIMEOUT: RPC レスポンスがタイムアウト

  • PARSE_ERROR: RPC メッセージの解析に失敗

注意事項

  • rpc メソッドは suspend 関数のため、コルーチンスコープ内で呼び出す必要があります

  • DataChannel 経由のシグナリングが有効で、かつ type: switched メッセージ受信後に利用可能です

  • 利用可能なメソッドは onOfferMessage コールバックで OfferMessage.rpcMethods から確認できます

  • 利用可能なメソッドは Sora の認証ウェブフックの払い出し結果に依存し、SDK 側では制御できません

  • isNotificationRequest = true を設定した場合、null が返ります

© Copyright 2018-2025, Shiguredo Inc. Created using Sphinx 9.1.0