# 如何導入 QNAP Room Service/SDK
## 角色及責任
1. QNAP Room Service (後續簡稱 QNAP): 提供建立 WebRTC 視訊所需要的信令 (signaling) 及 NAT 穿透 (NAT traversal) 機制
2. Your Backend Service (後續簡稱 Backend):
1. 提供撥打電話的 API, 並在此 API 中:
1. 使用 QNAP 提供的 API 金鑰簽發 JWT 給撥打方 (JWT 格式於後續說明)
2. 於 API 回應中提供撥打方 JWT
3. 使用 QNAP 提供的 API 金鑰簽發 JWT 給受話方 (JWT 格式於後續說明)
4. 以推播方式 (Push Kit, APNs, FCM...) 告知受話方同時並提供 JWT
2. 提供其它事件 API: 取消通話 (撥打方), 接聽通話 (受話方), 掛斷通話 (受話方)
3. Your Clients (後續簡稱 Caller/Callee):
1. 導入 Room SDK 以支援視訊/語音通話
2. 使用 Backend 提供的 API 撥打電話並取得 JWT (並實作 outgoing call 畫面)
3. 導入推播機制以接收來電通知及 JWT (並實作 incoming call 畫面)
4. Push Service (後續簡稱 Push): 提供推播服務, 依各行動平台而不同, 例如:
1. Push Kit: 適用於 iOS 發送整合 Call Kit 通話的來電事件
2. APNs:
1. 適用於 iOS 發送**不整合** Call Kit 的來電事件 (如受限中國地區法規)
2. 適用於 iOS 發送取消, 接聽, 掛斷等事件
3. FCM: 適用於 Android 發送所有通話事件
4. 小米/腾讯/...推播: 適用於中國地區 Android 發送所有通話事件
## 範例1: 撥打後受話方接聽
```sequence
Caller -> Backend: Make Call
Backend ->> Push: Call Event
Backend --> Caller: JWT
Caller -> Caller: Show Outgoing\nCall Screen
Caller -> QNAP: Join Room with JWT
Push ->> Callee: Call Event
Callee -> Callee: Show Incoming\nCall Screen
Callee -> Backend: Answer Call
Backend ->> Push: Answer Event
Backend --> Callee: OK
Callee -> QNAP: Join Room with JWT
Push ->> Caller: Answer Event
QNAP ->> Callee: Caller Joined
Callee -> Callee: Hide Incoming\nCall Screen
QNAP ->> Caller: Callee Joined
Caller -> Caller: Hide Outgoing\nCall Screen
```
## 範例2: 撥打後撥打方取消
```sequence
Caller -> Backend: Make Call
Backend ->> Push: Call Event
Backend --> Caller: JWT
Caller -> Caller: Show Outgoing\nCall Screen
Caller -> QNAP: Join Room with JWT
Push ->> Callee: Call Event
Callee -> Callee: Show Incoming\nCall Screen
Caller -> Backend: Cancel Call
Backend ->> Push: Cancel Event
Backend --> Caller: OK
Caller -> QNAP: Leave Room
Caller -> Caller: Hide Outgoing\nCall Screen
Push ->> Callee: Cancel Event
Callee -> Callee: Hide Incoming\nCall Screen
```
## 範例3: 撥打後受話方掛斷
```sequence
Caller -> Backend: Make Call
Backend ->> Push: Call Event
Backend --> Caller: JWT
Caller -> Caller: Show Outgoing\nCall Screen
Caller -> QNAP: Join Room with JWT
Push ->> Callee: Call Event
Callee -> Callee: Show Incoming\nCall Screen
Callee -> Backend: Reject Call
Backend ->> Push: Reject Event
Backend --> Callee: OK
Callee -> Callee: Hide Incoming\nCall Screen
Push ->> Caller: Reject Event
Caller -> QNAP: Leave Room
Caller -> Caller: Hide Outgoing\nCall Screen
```
## JWT 格式說明
在正式維運的環境中, 請勿使用 Quickstart 範例程式中使用的 GET /restful/v2/rooms/token API 來產生 JWT, 因為此 API 可能有外流您 API 金鑰的風險, 請務必在 Backend 中自行以 API 金鑰簽發 JWT.
JWT 標準規格, 範例及各種語言函式庫請參考其[官方網站](https://jwt.io/).
以下為存取 QNAP Room Service 的 JWT 標準欄位 (Standard Claims):
- exp: *integer*: 有效期限 (UTC秒)
- sub: *string*: QNAP 提供的 API 金鑰所屬專案 ID, 例如: PJb602298298664dd2b93c058de5bcb18f
- iss: *string*: NAP 提供的 API 金鑰 ID, 例如: SK80b4317d6f21441487c8f7dab75e7082
以下為存取 QNAP Room Service 的 JWT 客制欄位 (Private Claims):
- grant
- room
- name: *string*: 信令通道名稱, 建議於正式環境中每次通話配發一 UUID.
- type: *string*: 請固定使用 "peer-to-peer"
- turn: *boolean*: 設為 true 則可支援對稱式 NAT 的穿透, 但會有流量費用的發生.
- identity: *string*: 視訊成員的唯一識別碼, 在同一 room 內不可相同, 建議於正式環境中為各成員配發 UUID.
JWT 欄位範例:
```
{
"exp": 1585036871,
"iss": "SK80b4317d6f21441487c8f7dab75e7082",
"sub": "PJb602298298664dd2b93c058de5bcb18f",
"grant": {
"identity": "6266064224649216",
"room": {
"name": "267700004",
"type": "peer-to-peer",
"turn": true
}
}
}
```
QNAP Room Service 支援的簽章演算法:
* HS256
* HS512