.. _metadata: ####################### 任意の JSON 値の送受信 ####################### シグナリングメッセージの一部には、ユーザーが任意の JSON 値を送受信するためのフィールドが含まれます。 本章では JSON 値の送受信について説明します。 なお、シグナリングメッセージの詳細は `WebRTC SFU Sora ドキュメント - WebSocket 経由のシグナリング `_ を参照してください。 シグナリングメッセージ ========================== シグナリングメッセージは ``Signaling`` 列挙型と種別ごとのクラスで表されます。 メッセージの種別と対応する ``Signaling`` 列挙子の定義を次に示します。 詳細は :ref:`api` を参照してください。 - type: connect - ``Signaling.connect(SignalingConnect)`` - type: offer - ``Signaling.offer(SignalingOffer)`` - type: answer - ``Signaling.answer(SignalingAnswer)`` - type: update - ``Signaling.update(SignalingUpdate)`` - type: candidate - ``Signaling.candidate(SignalingCandidate)`` - type: notify(SignalingNotify) - ``Signaling.notify(SignalingNotify)`` - type: ping - ``Signaling.ping(SignalingPing)`` - type: pong - ``Signaling.pong(SignalingPong)`` - type: disconnect - ``Signaling.disconnect`` - type: push - ``Signaling.push(SignalingPush)`` 上記のうち、任意の JSON 値を含むことができるメッセージとプロパティを次に示します。 - type: connect (送信のみ) - ``metadata`` - ``notifyMetadata`` - type: notify (受信のみ) - ``authnMetadata`` - ``authzMetadata`` - ``metadata`` - type: push (受信のみ) - ``data`` 任意のJSON 値を送信する ======================= 任意の JSON 値を含むことができる送信用のメッセージは type: connect のみです。 ``metadata`` と ``notifyMetadata`` のメタデータを指定できます。 メタデータは ``Configuration`` の次のプロパティで指定できます。 どちらも ``Encodable`` プロトコルに準拠した値を指定します。 - ``metadata`` -> ``Configuration.signalingConnectMetadata`` - ``notifyMetadata`` -> ``Configuration.signalingConnectNotifyMetadata`` これらのプロパティの値は JSON に変換されて送信されます。 基本的なデータ型 (``Bool``, ``Int``, ``Float``, ``String``, ``Array``, ``Dictionary``) は ``Encodable`` に対応しているので、 これらの値の組み合わせであればエンコード処理を実装する必要はありません。 上記のプロパティの内容と生成される JSON を次に示します。 .. code-block:: swift // {"type":"connect", "metadata":"contents", ...} config.signalingConnectMetadata = "contents" // {"type":"connect", "metadata":{"key":"value"}, ...} config.signalingConnectMetadata = ["key": "value"] 送信されるメタデータの内容を確認するには、デバッグログを有効にしてシグナリングの内容をコンソールに出力してください。 詳細は :ref:`debug-log` を参照してください。 受信した任意の JSON 値を取得する ================================== 受信用のメッセージの type: notify と type: push の一部のプロパティは任意の JSON 値を含むことができます。 任意の JSON 値の型は ``Any?`` です。 受信した JSON 値は ``JSONSerialization`` クラスで解析されます。 解析後のオブジェクトは ``NSString``, ``NSNumber``, ``NSArray``, ``NSDictionary``, ``NSNull`` のいずれかです。 プロパティはシグナリング用のイベントハンドラで取得できます。 受信したメッセージ及び同メッセージを含む WebSocket メッセージを取得できるイベントハンドラを次に示します。 WebSocket メッセージはテキストなので、手動で JSON を解析する必要があります。 - ``MediaChannelHandlers.onReceiveSignaling``: 受信したメッセージを取得します。 - ``WebSocketChannelHandlers.onReceive``: 受信したメッセージを含む WebSocket メッセージを取得します。 イベントハンドラで JSON 値を取得する例を次に示します。 .. code-block:: swift // MediaChannelHandlers でメッセージを取得する mediaChannel.handlers.onReceiveSignaling = { signaling in switch signaling { // type: notify case .notify(let notify): switch notify.eventType { case "connection.created": // メタデータに含まれる JSON 値 (Any) を任意の型にキャストする if let metadata = notify.metadata as? [String: Any] { print("metadata => \(metadata)") } if let authnMetadata = notify.authnMetadata as? [String: Any] { print("authn => \(authnMetadata)") } if let authzMetadata = notify.authzMetadata as? [String: Any] { print("authz => \(authzMetadata)") } ... // 他のイベント種別でも同様に処理する case "connection.created": ... default: ... } // type: push case .push(let push): if let data = push.data as? [String: Any] { print("data => \(data)") } ... default: ... } } // WebSocket メッセージを手動で解析する場合 mediaChannel.webSocketChannel.handlers.onReceive = { message in switch message { case .text(let text): // 受信したシグナリングのテキストデータを JSON データとして解析する if let data = text.data(using: .utf8) { do { if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { switch json["type"] as? String { case "notify": // type: notify print("notify metadata => \(json["metadata"])") ... case "push": // type: push print("push data => \(json["data"])") ... default: ... } } } catch let error { // JSON の解析に失敗した場合のエラー処理 // ここに来ることはないので無視してよい } } ... case .binary(_): // シグナリングでバイナリデータは来ないので何もしなくてよい ... } }