RPC 機能¶
概要¶
RPC 機能は、 DataChannel 経由で JSON-RPC 2.0 による Sora の一部 HTTP API 呼び出しを行うための仕組みです。 Sora の RPC 機能については Sora のドキュメント RPC 機能 をご確認ください。
警告
この機能は実験的機能のため、正式版では仕様が変更される可能性があります。
設定¶
RPC 機能は DataChannel 経由のシグナリングが有効な場合に利用できます。
Sora iOS SDK では Configuration.dataChannelSignaling を true に設定してください。
var config = Configuration(url: soraURL,
channelId: soraChannelId,
role: role)
// DataChannel 経由のシグナリングを有効にする
config.dataChannelSignaling = true
RPC 用の DataChannel は Sora が label: "rpc" を持つチャネルとして作成します。
Configuration.dataChannels に rpc を指定する必要はありません。
利用できるメソッドの確認¶
利用可能な RPC メソッドは onReceiveSignaling で受信する Signaling.offer の rpcMethods から確認できます。
rpcMethods は [String]? で、メソッド名の文字列配列です。
mediaChannel.handlers.onReceiveSignaling = { signaling in
switch signaling {
case let .offer(offer):
guard let rpcMethods = offer.rpcMethods else {
return
}
// 例: ["2025.2.0/RequestSimulcastRid", ...]
print(rpcMethods)
default:
break
}
}
RPC を送信する¶
ユーザーは MediaChannel.rpc を利用して RPC を送信します。
MediaChannel.rpc の戻り値は RPCResponse<M.Result>? であり、 M.Result は呼び出したメソッドに対応した型になります。rpc 呼び出し時に is_notification_request を true に設定した場合は返り値が nil になります。
注釈
is_notification_request を true に設定すると Notification として利用できます。 これは Sora 側がレスポンスを返さないことを意味します。 Notification に関する詳細は https://www.jsonrpc.org/specification#notification をご確認ください。
RPC 機能のメソッドと SDK が提供する型の対応¶
Sora iOS SDK では以下の RPC メソッドが型として提供されます。
2025.2.0/RequestSimulcastRidに対応したRequestSimulcastRid2025.2.0/RequestSpotlightRidに対応したRequestSpotlightRid2025.2.0/ResetSpotlightRidに対応したResetSpotlightRid2025.2.0/PutSignalingNotifyMetadataに対応したPutSignalingNotifyMetadata<Metadata>2025.2.0/PutSignalingNotifyMetadataItemに対応したPutSignalingNotifyMetadataItem<Metadata, Value>
各メソッド型は RPCMethodProtocol を実装しており、メソッド固有のパラメータ型と結果型を持ちます。その型を用いて MediaChannel.rpc を呼んでください。
以下は RequestSimulcastRid と PutSignalingNotifyMetadataItem を呼び出すサンプルコードです。
RequestSimulcastRid の例¶
import Sora
func requestSimulcastRid(mediaChannel: MediaChannel) async throws {
// RequestSimulcastRidParams:
// rid: Rid
// senderConnectionId: String?
let params = RequestSimulcastRidParams(
rid: .r0,
senderConnectionId: "YOUR-SENDER-CONNECTION-ID")
do {
guard
let response = try await mediaChannel.rpc(
method: RequestSimulcastRid.self,
params: params,
is_notification_request: false,
timeout: 5.0)
else {
// RPC レスポンスが nil の場合
return
}
// response.result は RequestSimulcastRidResult で、プロパティで直接アクセス可能
let channelId = response.result.channelId
let receiverConnectionId = response.result.receiverConnectionId
let rid = response.result.rid
let senderConnectionId = response.result.senderConnectionId
_ = (channelId, receiverConnectionId, rid, senderConnectionId)
} catch SoraError.rpcUnavailable(let reason) {
// DataChannel が利用できない
_ = reason
} catch SoraError.rpcTimeout {
// 応答がタイムアウトした
} catch SoraError.rpcServerError(let detail) {
// Sora から JSON-RPC のエラー応答が返った
_ = detail
} catch {
// 予期しないエラー
_ = error
}
}
PutSignalingNotifyMetadataItem の例¶
import Sora
func putSignalingNotifyMetadataItem(mediaChannel: MediaChannel) async throws {
// メタデータアイテムの構造を定義
struct NewItem: Codable {
let foo: String
}
// メタデータ全体の構造を定義
struct Metadata: Codable {
let oldItem: String
let newItem: NewItem
enum CodingKeys: String, CodingKey {
case oldItem = "old_item"
case newItem = "new_item"
}
}
// PutSignalingNotifyMetadataItemParams<Value>:
// key: String
// value: Value
// push: Bool?
let params = PutSignalingNotifyMetadataItemParams(
key: "new_item",
value: NewItem(foo: "bar"))
do {
guard
let response = try await mediaChannel.rpc(
method: PutSignalingNotifyMetadataItem<Metadata, NewItem>.self,
params: params,
is_notification_request: false,
timeout: 5.0)
else {
// RPC レスポンスが nil の場合
return
}
// response.result は Metadata 型で、更新後のメタデータ全体が返される
let updated = response.result
_ = updated.oldItem
_ = updated.newItem
} catch SoraError.rpcUnavailable(let reason) {
// DataChannel が利用できない
_ = reason
} catch SoraError.rpcTimeout {
// 応答がタイムアウトした
} catch SoraError.rpcServerError(let detail) {
// Sora から JSON-RPC のエラー応答が返った
_ = detail
} catch {
// 予期しないエラー
_ = error
}
}
MediaChannel.rpc のレスポンスが不要な場合¶
レスポンスが不要な場合は is_notification_request を true にします。
この場合は JSON-RPC 2.0 の Notification として送信され、レスポンスを返しません。
do {
let params = RequestSimulcastRidParams(
rid: .r1,
senderConnectionId: "EKNQ103WRD4ZZ74B6TKRM9YK78")
_ = try await mediaChannel.rpc(
method: RequestSimulcastRid.self,
params: params,
is_notification_request: true,
timeout: 5.0)
} catch {
// 予期しないエラー
_ = error
}
MediaChannel.rpc について¶
MediaChannel.rpc はジェネリクスを使用します。
func rpc<M: RPCMethodProtocol>(
method: M.Type,
params: M.Params,
is_notification_request: Bool = false,
timeout: TimeInterval = 5.0
) async throws -> RPCResponse<M.Result>?
RPCMethodProtocol は以下のように定義されており、 Params と Result を RPC の各メソッドと関連付ける役割を持ちます。
public protocol RPCMethodProtocol {
associatedtype Params: Encodable
associatedtype Result: Decodable
static var name: String { get }
}
この関連付けにより、利用者は呼び出したメソッドに対応した結果型を扱えます。
例えば RequestSimulcastRid メソッドに対応する RequestSimulcastRid を指定した場合のレスポンスの型は RPCResponse<RequestSimulcastRidResult>? になります。
SDK で未提供の RPC メソッド型を定義する¶
Sora に新しい RPC メソッドが追加され、SDK 側でまだ型が提供されていない場合は、 RPCMethodProtocol を実装した型をユーザーが定義することで対応することができます。
Params は JSON-RPC 2.0 リクエストオブジェクトの params に入る値を表す型で、 Result は JSON-RPC 2.0 レスポンスオブジェクトの result に入る値を表す型です。
name には Sora に存在する RPC メソッド名を指定してください。
// リクエストパラメータ {"value": "hello"} を送信し
// {"accepted": true} のようにリザルトを受信する例です
struct CustomRPCParams: Encodable {
let value: String
}
struct CustomRPCResult: Decodable {
let accepted: Bool
}
struct CustomRPCMethod: RPCMethodProtocol {
typealias Params = CustomRPCParams
typealias Result = CustomRPCResult
static let name = "2025.2.0/CustomRPCMethod"
}
let params = CustomRPCParams(value: "hello")
let response = try await mediaChannel.rpc(
method: CustomRPCMethod.self,
params: params)
_ = response?.result.accepted