---
lang: ja
path: user-guide/commons/default-room
labels: ユーザーガイド/その他 共通仕様/RoomとP2PRoom・SFURoomの併用
metaTitle: RoomとP2PRoom/SFURoomの併用 ｜ その他 共通仕様 ｜ ユーザーガイド ｜ SkyWay（スカイウェイ）
---

# 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 などのリソース管理が複雑になる問題がありました。

```javascript
// 通信方式を指定してP2PRoomを作成する
const room = await SkyWayRoom.FindOrCreate(context, { type: "p2p" });
const me = await room.join();

// 通信方式は必ずP2Pになる
await me.publish(audio);
```

一方、Room は作成した時点ではなく、Publish 時に通信方式を指定します。

```javascript
// 作成時点では通信方式が固定されない
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用)](/ja/docs/user-guide/authentication/skyway-auth-token/)のページをご参照ください。
> 
> 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

```javascript
// Publisher側（SFURoomを使用）
const room = await SkyWayRoom.FindOrCreate(context, { type: "sfu", name: "room1" });
const me = await room.join();
await me.publish(audio);
```

```javascript
// 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

```swift
// 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)
```

```swift
// 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

```kotlin
// Publisher側（SFURoomを使用）
val room = SFURoom.findOrCreate(name = "room1")
val me = room?.join(memberInit)
me.publish(audio)
```

```kotlin
// 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 してください。
