RoomとP2PRoom・SFURoomの併用
概要
Room(type: default。以下 Room)は P2P 通信と SFU 通信を同一 Room 内で Publish することが可能な新しいタイプの Room です。
Room を使うことで、以下のユースケースに対応できます。
- 録音・録画(SFUを利用)と同時に P2P で通話を行う
- SFU で通話をしながら P2P でデータ通信を行う
- 人数に応じて P2P/SFU での通話を使い分ける
Room は既存の P2PRoom および SFURoom と相互接続が可能であり、アプリ側で段階的に移行することが可能です。
Roomに対応しているSDK
2025年10月現在、Room に対応している SDK は以下の通りです。
- JavaScript SDK(v2.0.0以降)
- iOS SDK(v3.1.0以降)
- Android SDK(v3.3.0以降)
P2PRoom/SFURoomとの違い
P2PRoom/SFURoom は、作成した時点で通信方式が固定されます。 P2P と SFU を併用したい場合はそれぞれに対応する Room を作成する必要があり、SkyWay Auth Token や Member などのリソース管理が複雑になる問題がありました。
// 通信方式を指定してP2PRoomを作成する const room = await SkyWayRoom.FindOrCreate(context, { type: "p2p" }); const me = await room.join(); // 通信方式は必ずP2Pになる await me.publish(audio);
一方、Room は作成した時点ではなく、Publish 時に通信方式を指定します。
// 作成時点では通信方式が固定されない const room = await SkyWayRoom.FindOrCreate(context); const me = await room.join(); // Publish時に通信方式指定する await me.publish(audio, {type: "p2p"}); // 同一Memberから異なる通信方式でPublishすることもできる await me.publish(video, {type: "sfu"});
このように、1つの Room 内で P2P と SFU を柔軟に併用できます。
Room は、内部的に SFURoom の機能を利用します。 そのため、Room を利用する場合は SkyWay Auth Token にて SFU リソースの認可が必要です。
SkyWay Auth Token の詳細については、SkyWay Auth Token(各種SDK用)のページをご参照ください。
Room の作成時に SFU リソースが認可されていない場合、以下のような挙動となります。
以下のバージョンのSDKを利用する場合、Room の作成に失敗します
SDKの種類 バージョン JS SDK v2.2.0 ~ v2.2.1 iOS SDK v3.1.0 ~ v3.1.1 Android SDK v3.3.0 ~ v3.3.3 以下のバージョンのSDKを利用する場合、Room の作成は可能ですが、SFU 方式の Publish に失敗します(P2P 方式の Publish は問題なくご利用いただけます)
SDKの種類 バージョン JS SDK v2.3.0以降 iOS SDK v3.2.0以降 Android SDK v3.4.0以降
P2PRoom/SFURoomとの相互接続
SDK のアップデート時に、Room を利用するアプリと P2PRoom/SFURoom を利用するアプリが混在するケースがあります。 この場合、Room と P2PRoom/SFURoom を相互に接続することが可能です。
ただし、注意点があります。 Room に対応していないバージョンの SDK において SFURoom から Publish を行った場合、対向の Room からは Publication が2つあるように見えます。 そのため、イベントをハンドリングする際にフィルター処理を行う必要があります。
JavaScript SDK
// Publisher側(SFURoomを使用) const room = await SkyWayRoom.FindOrCreate(context, { type: "sfu", name: "room1" }); const me = await room.join(); await me.publish(audio);
// Subscriber側(Roomを使用) const room = await SkyWayRoom.FindOrCreate(context, { name: "room1" }); const me = await room.join(); room.onStreamPublished.add((e) => { // P2PのPublicationの場合はスキップする if (e.publication.type == "p2p") return me.subscribe(e.publication) });
iOS SDK
// Publisher側(SFURoomを使用) let roomInit: Room.InitOptions = .init() roomInit.name = "room1" let room = try? await SFURoom.findOrCreate(with: roomInit) let me = try? await room?.join(with: nil) _ = try? await me?.publish(audio, options: nil)
// Subscriber側(Roomを使用) let roomInit: Room.InitOptions = .init() roomInit.name = "room1" self.room = try? await Room.findOrCreate(with: roomInit) self.room?.delegate = self self.me = try? await self.room?.join(with: nil) // MARK: - RoomDelegate func room(_ room: Room, didPublishStreamOf publication: RoomPublication) { if publication.type == .P2P { return } Task { try? await self.me?.subscribe(publicationId: publication.id, options: nil) } }
Android SDK
// Publisher側(SFURoomを使用) val room = SFURoom.findOrCreate(name = "room1") val me = room?.join(memberInit) me.publish(audio)
// Subscriber側(Roomを使用) val room = SFURoom.findOrCreate(name = "room1") val me = room?.join(memberInit) room?.onStreamPublishedHandler = Any@{ // P2PのPublicationの場合はスキップする if (it.type == RoomPublication.Type.P2P) return@Any me.subscribe(it) }
通信方式の切り替え
Publish した後に通信方式を変更することはできません。 通信方式を切り替えたい場合は、一度 Unpublish してから再度 type を変更して Publish してください。