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 は label: "rpc" の DataChannel が OPEN になった後に利用できます。
Sora iOS SDK では mediaChannel.handlers.onDataChannelOpened で label == "rpc" を受け取った時点から利用可能です。
mediaChannel.handlers.onDataChannelOpened = { mediaChannel, label in
guard label == "rpc" else {
return
}
Task {
do {
let params = RequestSimulcastRidParams(
rid: .r1,
senderConnectionId: "EKNQ103WRD4ZZ74B6TKRM9YK78")
_ = try await mediaChannel.rpc(
method: RequestSimulcastRid.self,
params: params)
} catch {
// 予期しないエラー
_ = error
}
}
}
MediaChannel.rpc の戻り値は RPCResponse<M.Result>? であり、 M.Result は呼び出したメソッドに対応した型になります。rpc 呼び出し時に is_notification_request を true に設定した場合は返り値が nil になります。
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
Swift 6 言語モードに対応する Sendable な RPC を利用する¶
MediaChannel.sendableRPC(method:params:isNotificationRequest:timeout:) は、 MediaChannel.rpc と同じ挙動で、 Swift 6 言語モードの検査に対応した RPC メソッドを呼び出します。
引数と、 jsonrpc / id / result の意味、 notification で nil が返ること、失敗時に SoraError が投げられることは MediaChannel.rpc と共通です。
MediaChannel.sendableRPC は MediaChannel.rpc に対して以下の 2 点が異なります。
- 呼び出せるのは
SendableRPCMethodProtocolに準拠したメソッドだけです - 戻り値は
SendableRPCResponse<M.Result>?です
SendableRPCResponse は Result が Sendable な場合だけ Sendable に準拠できるため、応答を actor 境界や Task の @Sendable クロージャへ渡せます。
そのため、 params と result を actor 境界や @Sendable クロージャへ渡す場合は MediaChannel.sendableRPC を使ってください。
MediaChannel.sendableRPC は Swift 5 言語モードでも呼び出せます。
ただし、 actor 境界や @Sendable クロージャを越える値の検査が有効になるのは Swift 6 言語モードです。
利用者定義のメソッドを呼び出す¶
SDK で未提供のメソッドは、 Sendable な Params / Result を関連付けた SendableRPCMethodProtocol 準拠型を定義して呼び出します。
SendableRPCMethodProtocol は RPCMethodProtocol を継承し、 Params と Result に Sendable を要求します。
// リクエストパラメーター {"value": "hello"} を送信し
// {"accepted": true} のようにリザルトを受信する例です
// Params と Result が Sendable のため SendableRPCMethodProtocol へ準拠できる
struct CustomRPCParams: Encodable, Sendable {
let value: String
}
struct CustomRPCResult: Decodable, Sendable {
let accepted: Bool
}
enum CustomRPCMethod: SendableRPCMethodProtocol {
typealias Params = CustomRPCParams
typealias Result = CustomRPCResult
static let name = "2025.2.0/CustomRPCMethod"
}
let response = try await mediaChannel.sendableRPC(
method: CustomRPCMethod.self,
params: CustomRPCParams(value: "hello"))
Sendable ではない Params / Result を使う既存の利用者定義メソッドは、これまでどおり MediaChannel.rpc を利用してください。
SendableRPCMethodProtocol へ準拠させるには、非 Sendable な型を Sendable な型へ変更する必要があります。
SendableRPCResponse を actor へ渡す¶
SendableRPCResponse<CustomRPCResult> は Sendable のため、応答を actor 境界や Task の @Sendable クロージャへそのまま渡せます。
actor RPCResultStore {
private var accepted: Bool?
func store(_ response: SendableRPCResponse<CustomRPCResult>) {
// response.result は CustomRPCResult で、プロパティで直接アクセス可能
accepted = response.result.accepted
}
}
組み込みメソッドを呼び出す¶
RequestSimulcastRid / RequestSpotlightRid / ResetSpotlightRid は新旧両方の protocol へ準拠しているため、 MediaChannel.rpc と MediaChannel.sendableRPC のどちらからも呼び出せます。
RequestSimulcastRid を MediaChannel.sendableRPC で呼び出した場合のレスポンスの型は SendableRPCResponse<RequestSimulcastRidResult>? になります。
let params = RequestSimulcastRidParams(
rid: .r0,
senderConnectionId: "YOUR-SENDER-CONNECTION-ID")
guard
let response = try await mediaChannel.sendableRPC(
method: RequestSimulcastRid.self,
params: params,
isNotificationRequest: false,
timeout: 5.0)
else {
// 応答が返らなかった場合
return
}
// response.result は RequestSimulcastRidResult で、プロパティで直接アクセス可能
let channelId = response.result.channelId
ジェネリックな組み込みメソッドを呼び出す¶
PutSignalingNotifyMetadata / PutSignalingNotifyMetadataItem は型パラメータに Sendable を要求しないため、 SendableRPCMethodProtocol へ準拠できません。
actor 境界や @Sendable クロージャへ渡す場合は、型パラメータに Sendable を要求する SendablePutSignalingNotifyMetadata / SendablePutSignalingNotifyMetadataItem を使ってください。
RPC メソッド名は既存の PutSignalingNotifyMetadata / PutSignalingNotifyMetadataItem と同じです。
SendablePutSignalingNotifyMetadata<Metadata>はMetadataがCodable & Sendableの場合に利用しますSendablePutSignalingNotifyMetadataItem<Metadata, Value>はMetadataがDecodable & Sendable、ValueがEncodable & Sendableの場合に利用します
struct NewItem: Codable, Sendable {
let foo: String
}
struct Metadata: Codable, Sendable {
let oldItem: String
let newItem: NewItem
}
let params = PutSignalingNotifyMetadataItemParams(
key: "new_item",
value: NewItem(foo: "bar"))
guard
let response = try await mediaChannel.sendableRPC(
method: SendablePutSignalingNotifyMetadataItem<Metadata, NewItem>.self,
params: params,
isNotificationRequest: false,
timeout: 5.0)
else {
// 応答が返らなかった場合
return
}
// response.result は Metadata 型で、更新後のメタデータ全体が返される
let updated = response.result
任意の JSON を送受信する¶
参照型や可変状態を持つ型は Sendable を満たせないため、任意の JSON を送受信する場合は Sendable へ準拠した JSONValue を利用します。
JSONValue は SendableRPCMethodProtocol の Params / Result としてそのまま利用できます。
// JSONValue.object は [String: JSONValue] のため、任意の JSON を Sendable のまま組み立てられる
let metadata: JSONValue = .object(["app_name": .string("sora-ios-sdk")])
guard
let response = try await mediaChannel.sendableRPC(
method: SendablePutSignalingNotifyMetadata<JSONValue>.self,
params: PutSignalingNotifyMetadataParams(metadata: metadata))
else {
// 応答が返らなかった場合
return
}
// response.result は JSONValue のため、case 分岐で読み出す
if case .object(let fields) = response.result {
_ = fields["app_name"]
}
notification を送る¶
isNotificationRequest に true を指定すると JSON-RPC 2.0 の Notification として送信され、 Sora は応答を返さないため戻り値は nil になります。
この挙動も MediaChannel.rpc と共通です。
// notification は応答を待たないため、戻り値の SendableRPCResponse? は nil になる
let response = try await mediaChannel.sendableRPC(
method: RequestSimulcastRid.self,
params: params,
isNotificationRequest: true,
timeout: 5.0)
エラーを扱う¶
失敗時に SoraError が投げられることも MediaChannel.rpc と共通です。
SoraError.rpcServerError が運ぶ RPCErrorDetail は Sendable で、 RPCErrorDetail.data は JSON-RPC 2.0 の error.data を表す JSONValue? です。
error.data が省略された場合は nil 、 null の場合は .null になります。
do {
_ = try await mediaChannel.sendableRPC(
method: RequestSimulcastRid.self,
params: params,
isNotificationRequest: false,
timeout: 5.0)
} catch SoraError.rpcServerError(let detail) {
// detail.code と detail.message は JSON-RPC 2.0 の error.code と error.message になる
_ = detail.code
_ = detail.message
// detail.data は error.data が省略された場合は nil、null の場合は .null になる
switch detail.data {
case .some(.object(let errorData)):
_ = errorData
case .some(let value):
_ = value
case .none:
break
}
} catch {
// 予期しないエラー
_ = error
}
Sendable な RPC のサンプルコード¶
import Sora
// MARK: - 利用者定義の RPC メソッド
/// 利用者定義の RPC メソッドのパラメーター。
/// Params と Result が Sendable のため、SendableRPCMethodProtocol へ準拠できる。
struct CustomRPCParams: Encodable, Sendable {
let value: String
}
/// 利用者定義の RPC メソッドの実行結果。
struct CustomRPCResult: Decodable, Sendable {
let accepted: Bool
}
/// 利用者定義の RPC メソッド。
/// SendableRPCMethodProtocol は RPCMethodProtocol を継承し、Params と Result に Sendable を要求する。
enum CustomRPCMethod: SendableRPCMethodProtocol {
typealias Params = CustomRPCParams
typealias Result = CustomRPCResult
static let name = "2025.2.0/CustomRPCMethod"
}
// MARK: - SendableRPCResponse を actor へ渡す
/// SendableRPCResponse を受け取る actor。
///
/// SendableRPCResponse<CustomRPCResult> は Sendable のため、actor 境界を越えて渡せる。
actor RPCResultStore {
private var accepted: Bool?
func store(_ response: SendableRPCResponse<CustomRPCResult>) {
// response.result は CustomRPCResult で、プロパティで直接アクセス可能
accepted = response.result.accepted
}
func currentAccepted() -> Bool? {
accepted
}
}
/// MediaChannel 自体は Sendable ではないため、チャネルを actor 境界や Task へ渡す場合は
/// nonisolated(unsafe) などの隔離が必要になる。これは rpc / sendableRPC のどちらでも同じ。
/// sendableRPC が不要にするのは params / result / SendableRPCResponse を渡す際の回避策で、
/// ここでは Sendable な SendableRPCResponse だけを actor へ渡すのが要点になる。
final class SendableRPCExample {
nonisolated(unsafe) let mediaChannel: MediaChannel
let store = RPCResultStore()
init(mediaChannel: MediaChannel) {
self.mediaChannel = mediaChannel
}
/// SendableRPCMethodProtocol 準拠の利用者定義メソッドを sendableRPC で呼び出す。
func callCustomMethod() async throws {
do {
guard
let response = try await mediaChannel.sendableRPC(
method: CustomRPCMethod.self,
params: CustomRPCParams(value: "hello"),
isNotificationRequest: false,
timeout: 5.0)
else {
// 応答が返らなかった場合
return
}
// response は SendableRPCResponse<CustomRPCResult> です。 RPCResponse と同じ挙動で、
// Swift 6 言語モードの検査に対応した型のため、actor 境界や @Sendable クロージャへ渡せます。
await store.store(response)
} catch SoraError.rpcUnavailable(let reason) {
// DataChannel が利用できない
_ = reason
} catch SoraError.rpcTimeout {
// 応答がタイムアウトした
} catch SoraError.rpcServerError(let detail) {
// Sora から JSON-RPC のエラー応答が返った
_ = detail
} catch {
// 予期しないエラー
_ = error
}
}
}
// MARK: - 組み込みメソッドを timeout 付きで呼び @Sendable クロージャへ渡す
/// 組み込みの RequestSimulcastRid は SendableRPCMethodProtocol へも準拠しているため、
/// sendableRPC からも呼び出せる。戻り値は SendableRPCResponse<RequestSimulcastRidResult>? になる。
func requestSimulcastRidSendable(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.sendableRPC(
method: RequestSimulcastRid.self,
params: params,
isNotificationRequest: false,
timeout: 5.0)
else {
// 応答が返らなかった場合
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)
// @Sendable クロージャへ渡す場合は、クロージャの外側の値をキャプチャできるかが検査される。
// SendableRPCResponse は Sendable のため、そのままキャプチャできる。
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
Task { @Sendable in
_ = response.result.channelId
continuation.resume()
}
}
} catch SoraError.rpcUnavailable(let reason) {
// DataChannel が利用できない
_ = reason
} catch SoraError.rpcTimeout {
// 応答がタイムアウトした
} catch SoraError.rpcServerError(let detail) {
// Sora から JSON-RPC のエラー応答が返った
_ = detail
} catch {
// 予期しないエラー
_ = error
}
}
// MARK: - notification として送信する
/// isNotificationRequest に true を指定すると JSON-RPC 2.0 の Notification として送信され、
/// Sora は応答を返さないため戻り値は nil になる。この挙動も rpc と共通になる。
func requestSimulcastRidAsNotification(mediaChannel: MediaChannel) async throws {
let params = RequestSimulcastRidParams(
rid: .r0,
senderConnectionId: "YOUR-SENDER-CONNECTION-ID")
do {
// notification は応答を待たないため、戻り値の SendableRPCResponse? は nil になる
let response = try await mediaChannel.sendableRPC(
method: RequestSimulcastRid.self,
params: params,
isNotificationRequest: true,
timeout: 5.0)
_ = response
} catch SoraError.rpcUnavailable(let reason) {
// DataChannel が利用できない
_ = reason
} catch SoraError.rpcTimeout {
// 応答がタイムアウトした
} catch SoraError.rpcServerError(let detail) {
// Sora から JSON-RPC のエラー応答が返った
_ = detail
} catch {
// 予期しないエラー
_ = error
}
}
// MARK: - ジェネリックな組み込みメソッドを Sendable 版の型で呼び出す
/// シグナリング通知メタデータのアイテムを設定する。
/// ジェネリックな組み込みメソッドは、actor 境界や @Sendable クロージャへ渡す場合に Sendable 版の型を使う。
func putSignalingNotifyMetadataItemSendable(mediaChannel: MediaChannel) async throws {
// メタデータアイテムの構造を定義する。Value は Encodable & Sendable が必要になる
struct NewItem: Codable, Sendable {
let foo: String
}
// メタデータ全体の構造を定義する。Metadata は Decodable & Sendable が必要になる
struct Metadata: Codable, Sendable {
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.sendableRPC(
method: SendablePutSignalingNotifyMetadataItem<Metadata, NewItem>.self,
params: params,
isNotificationRequest: false,
timeout: 5.0)
else {
// 応答が返らなかった場合
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
}
}
// MARK: - 辞書を受け取る組み込みメソッドを JSONValue で呼び出す
/// 参照型や可変状態を持つ型は Sendable を満たせないため、任意の JSON を送受信する場合は
/// Sendable へ準拠した JSONValue を使う。ここでは辞書をメタデータとして送信する。
func putSignalingNotifyMetadataWithJSONValue(mediaChannel: MediaChannel) async throws {
// JSONValue.object は [String: JSONValue] のため、任意の JSON を Sendable のまま組み立てられる
let metadata: JSONValue = .object(["app_name": .string("sora-ios-sdk")])
do {
guard
let response = try await mediaChannel.sendableRPC(
method: SendablePutSignalingNotifyMetadata<JSONValue>.self,
params: PutSignalingNotifyMetadataParams(metadata: metadata),
isNotificationRequest: false,
timeout: 5.0)
else {
// 応答が返らなかった場合
return
}
// response.result は JSONValue のため、case 分岐で読み出す
if case .object(let fields) = response.result {
_ = fields["app_name"]
}
} catch SoraError.rpcUnavailable(let reason) {
// DataChannel が利用できない
_ = reason
} catch SoraError.rpcTimeout {
// 応答がタイムアウトした
} catch SoraError.rpcServerError(let detail) {
// Sora から JSON-RPC のエラー応答が返った
_ = detail
} catch {
// 予期しないエラー
_ = error
}
}
// MARK: - エラー応答から JSON-RPC 2.0 のエラー詳細を取り出す
/// 失敗時に SoraError が投げられることも rpc と共通になる。
/// SoraError.rpcServerError が運ぶ RPCErrorDetail は Sendable で、
/// detail.data は JSON-RPC 2.0 の error.data を表す JSONValue? になる。
func describeSendableRPCError(mediaChannel: MediaChannel) async throws {
let params = RequestSimulcastRidParams(
rid: .r0,
senderConnectionId: "YOUR-SENDER-CONNECTION-ID")
do {
_ = try await mediaChannel.sendableRPC(
method: RequestSimulcastRid.self,
params: params,
isNotificationRequest: false,
timeout: 5.0)
} catch SoraError.rpcServerError(let detail) {
// detail.code と detail.message は JSON-RPC 2.0 の error.code と error.message になる
_ = detail.code
_ = detail.message
// detail.data は error.data が省略された場合は nil、null の場合は .null になる
switch detail.data {
case .some(.object(let errorData)):
_ = errorData
case .some(let value):
_ = value
case .none:
// error.data が省略された場合
break
}
} catch {
// 予期しないエラー
_ = error
}
}