WebSocket API
概述¶
WebSocket API 透過 WebSocket 與 Socket 伺服器進行通信來提供聊天服務。它支持遊戲客戶端連接、頻道消息傳輸等功能。
WebSocket API 的主要特點如下。
- 客戶端連接 / 斷開連接
- PING / PONG
- 發送 / 接收聊天消息
- 頻道聊天
- 1:1 聊天
- 過濾被封鎖的用戶
- 不向被封鎖的用戶發送消息
- 不接收來自被封鎖的用戶的消息
- 頻道進入和退出通知
基本信息¶
這提供了使用 WebSocket API 時您需要知道的基本信息。
主要術語¶
- 頻道: 聊天室
- 頻道消息: 發送給頻道中所有用戶的聊天消息
- 1:1 消息: 僅發送給特定用戶的聊天消息
封包類型¶
與套接字伺服器進行發送和接收的數據包類型如下。
封包名稱 | 描述 |
---|---|
連接 | 連接到套接字伺服器 |
回應連接 | 對連接請求的回應 |
重新連接 | 重新連接到套接字伺服器 |
回應重新連接 | 對重新連接請求的回應 |
PING | 保持連接活躍 如果在連接尚未成功時請求 PING,伺服器將會斷開連接。 |
PONG | 對 PING 請求的回應 |
頻道聊天 | 頻道聊天 |
回應頻道聊天 | 對頻道聊天請求的回應 |
直接聊天 | 1:1 聊天 |
回應直接聊天 | 對直接聊天請求的回應 |
通知進入頻道 | 頻道進入消息 |
通知退出頻道 | 頻道退出消息 |
通知刪除頻道 | 頻道刪除消息 |
通知頻道通知 | 頻道通知消息 |
通知消息 | 用戶通知消息 |
通知頻道聊天 | 頻道聊天消息 |
通知直接聊天 | 1:1 聊天消息 |
套接字連接過程¶
-
透過遊戲伺服器的聊天 Http API 請求發行令牌。※ 發行的令牌用於連接聊天 Socket 伺服器
- 使用 Hive 認證金鑰請求 用戶令牌發行 API
-
應用客戶端請求連接到 Socket 伺服器
- WebSocket 通信
- 使用第 1 步發出的令牌
- 如果連接成功,Socket 伺服器將返回以下信息
插座斷開¶
當WebSocket連接被終止時,伺服器執行以下操作。
- 退出參與的頻道並發送退出通知消息
- 刪除連接信息
插座通信結構¶
WebSocket 通信是以 JSON 格式进行的。请求数据包格式如下。
{
"packetType":"Packet type",
"correlationId":"Identifier for matching the response to the request",
"body": {
// JSON data according to packetType
}
}
以下是响应数据包格式。
{
"packetType":"Packet type (starts with RESPONSE)",
"correlationId":"Identifier for matching the response to the request",
"status":"Status code",
"message":"Status message",
"body": // JSON Object
}
以下是伺服器訊息封包格式。
{
"packetType":"Packet type (starts with NOTIFY)",
"body":{
// JSON data according to packetType
}
}
當伺服器斷開 WebSocket 連接時,以下情況適用。
- 如果客戶端在 1 分鐘內沒有請求
- 如果不是 JSON 格式
- 當狀態值為 401 或 403
- 401 未授權
- 403 禁止
- 如果從另一個會話訪問,終止現有會話
回應代碼¶
這是回應狀態碼。
狀態碼 | 狀態訊息 | 描述 |
---|---|---|
200 | 成功。 | 成功 |
400 | 錯誤的請求 | 錯誤的請求 |
401 | 未授權 | 未授權 |
403 | 禁止 | 伺服器禁止 |
408 | 請求超時 | 由於客戶端60秒內沒有請求,伺服器關閉了連接 |
409 | 衝突 | 使用者的請求與伺服器狀態衝突(例如,當1:1聊天夥伴離線時) |
500 | 內部伺服器錯誤 | 內部伺服器錯誤 |
Websocket API 功能¶
這解釋了聊天服務中使用的WebSocket API每個功能的API請求和響應,以及示例代碼。
客戶端連接¶
請求參數¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 客戶端連接命令 (CONNECT ) | 字串 | 是 |
body | 請求數據 | 物件 | 是 |
請求參數 > 主體¶
字段名稱 | 描述 | 類型 | 必填 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | 是 | 例如 1 |
playerId | 帳戶識別碼 Hive 玩家 ID | 長整數 | 是 | 例如 1234 |
langCode | Hive 語言代碼 (基於 ISO 639 alpha-2,未由 ISO 639 alpha-2 區分的語言由 Script 標籤分隔) | 字串 | 是 | 例如 "en" |
loginKey | 用於訪問的令牌 由 Chat Http API 發出 | 字串 | 是 | "eyJhbGciOiJIUzI1NiJ9.eyJnYW1lSW5kZXgiOjEsInBsYXllcklkIjoxMjM0LCJpYXQiOjE3MzAzNjY4MjksImV4cCI6MTczMDM3MDQyOX0.fpg6kqwqp1QN3KuYcjVBr8j0mzjN2doefJ_D6xFxcFY" |
回應主體¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 連接請求的回應 (RESPONSE_CONNECT ) | 字串 | 是 |
status | 狀態碼 | 整數 | 是 |
message | 狀態訊息 | 字串 | 是 |
body | 返回的數據 | 物件 | 是 |
回應主體 > 主體¶
欄位名稱 | 描述 | 類型 | 必填 | 範例 |
---|---|---|---|---|
sessionId | 成功連接後返回的值 | 字串 | Y | 例如 "005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76" |
請求範例¶
{
"packetType": "CONNECT",
"body":{
"gameIndex":1,
"playerId": 1234,
"langCode": "en",
"loginKey": "eyJhbGciOiJIUzI1NiJ9.eyJnYW1lSW5kZXgiOjEsInBsYXllcklkIjoxMjM0LCJpYXQiOjE3MzAzNjY4MjksImV4cCI6MTczMDM3MDQyOX0.fpg6kqwqp1QN3KuYcjVBr8j0mzjN2doefJ_D6xFxcFY" // API 서버에서 생성한 JWT
}
}
回應範例¶
{
"packetType":"RESPONSE_CONNECT",
"status": 200,
"message":"OK",
"body":{
"sessionId":"005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76"
}
}
客戶端重新連接¶
提供了重新连接功能,因为WebSocket连接可能会根据网络情况而断开。如果在WebSocket断开后的10分钟内发出RECONNECT
请求,您将重新加入您之前参与的频道。
請求參數¶
欄位名稱 | 描述 | 類型 | 是否必填 |
---|---|---|---|
packetType | 客戶端重新連接命令 (RECONNECT ) | 字串 | 是 |
body | 請求資料 | 物件 | 是 |
請求參數 > 主體¶
字段名称 | 描述 | 类型 | 必需 | 示例 |
---|---|---|---|---|
gameIndex | Hive 游戏索引 | 整数 | Y | 例如 1 |
playerId | 账户标识符 Hive 玩家 ID | 长整型 | Y | 例如 1234 |
langCode | Hive 语言代码 (基于 ISO 639 alpha-2,ISO 639 alpha-2 无法区分的语言由脚本标签分隔) | 字符串 | Y | 例如 "en" |
loginKey | 用于访问的令牌 从 Chat Http API 颁发 | 字符串 | Y | "eyJhbGciOiJIUzI1NiJ9.eyJnYW1lSW5kZXgiOjEsInBsYXllcklkIjoxMjM0LCJpYXQiOjE3MzAzNjY4MjksImV4cCI6MTczMDM3MDQyOX0.fpg6kqwqp1QN3KuYcjVBr8j0mzjN2doefJ_D6xFxcFY" |
回應主體¶
字段名称 | 描述 | 类型 | 必需 |
---|---|---|---|
packetType | 对重连请求的响应(RESPONSE_RECONNECT ) | 字符串 | 是 |
status | 状态码 | 整数 | 是 |
message | 状态消息 | 字符串 | 是 |
body | 返回的数据 | 对象 | 是 |
回應主體 > 主體¶
欄位名稱 | 描述 | 類型 | 必需 | 範例 |
---|---|---|---|---|
sessionId | 連接成功後返回的值 | 字串 | 是 | 例如 "005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76" |
channelIds | 從先前參加的頻道成功加入的頻道列表 | 字串陣列 | 是 | 例如 ["ch:1", "ch:2"] |
failChannelIds | 從先前參加的頻道未能加入的頻道列表 | 字串陣列 | 是 | 例如 [] |
請求範例¶
{
"packetType": "RECONNECT",
"body":{
"gameIndex":1,
"playerId": 1234,
"langCode": "en",
"loginKey": "eyJhbGciOiJIUzI1NiJ9.eyJnYW1lSW5kZXgiOjEsInBsYXllcklkIjoxMjM0LCJpYXQiOjE3MzAzNjY4MjksImV4cCI6MTczMDM3MDQyOX0.fpg6kqwqp1QN3KuYcjVBr8j0mzjN2doefJ_D6xFxcFY" // JWT generated from the API server
}
}
回應範例¶
{
"packetType":"RESPONSE_RECONNECT",
"status": 200,
"message":"OK",
"body":{
"sessionId":"005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76",
"channelIds":["ch:1", "ch:2"], // List of channels successfully joined from previously participated channels
"failChannelIds":[] // List of channels that failed to join from previously participated channels
}
}
Ping / Pong¶
- 當套接字伺服器和 CONNECT 完成時,請求才有效。
- 如果沒有 PONG 回應,則需要重新登錄。
請求參數¶
欄位名稱 | 描述 | 類型 | 必需 |
---|---|---|---|
packetType | PING 請求命令 (PING ) | 字串 | Y |
回應主體¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | PONG 回應命令 (PONG ) | 字串 | Y |
請求範例¶
回應範例¶
頻道消息發送¶
請求參數¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 通道消息傳輸命令 (CHANNEL_CHAT ) | 字串 | Y |
body | 請求數據 | 物件 | Y |
請求參數 > 主體¶
字段名称 | 描述 | 类型 | 必需 | 示例 |
---|---|---|---|---|
gameIndex | Hive 游戏索引 | 整数 | 是 | 例如 1 |
from | 发送消息到频道的账户标识符 Hive 玩家 ID | 长整型 | 是 | 例如 1234 |
to | 发送消息到频道的频道 ID 聊天 HTTP API 创建的 | 字符串 | 是 | 例如 "open:1" |
message | 发送到频道的消息 (最多 200 个字符) | 字符串 | 是 | 例如 "Hello World!" |
extraData | 消息的附加信息 (UTF-8 基础)(最多 256 字节) | 字符串 | 是 | 例如 "bbbb" |
langCode | 发送消息的语言代码 Hive 语言代码 (基于 ISO 639 alpha-2,未通过 ISO 639 alpha-2 区分的语言应通过脚本标签分隔) | 字符串 | 是 | 例如 "en" |
回應主體¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 對頻道消息傳輸的回應 (RESPONSE_CHANNEL_CHAT ) | 字串 | 是 |
status | 狀態碼 | 整數 | 是 |
message | 狀態消息 | 字串 | 是 |
請求範例¶
{
"packetType":"CHANNEL_CHAT",
"body": {
"gameIndex": 1,
"from": 1234,
"to": "open:1",
"message": "Hello World!",
"extraData": "bbbb",
"langCode": "en"
}
}
回應範例¶
1:1 訊息發送¶
請求參數¶
欄位名稱 | 描述 | 類型 | 必需 |
---|---|---|---|
packetType | 1:1 消息傳輸命令 (DIRECT_CHAT ) | 字串 | Y |
body | 請求數據 | 物件 | Y |
請求參數 > 主體¶
字段名稱 | 描述 | 類型 | 必需 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | Y | 例如 1 |
from | 1:1 訊息發送者帳戶識別碼 Hive 玩家 ID | 長整數 | Y | 例如 1234 |
to | 1:1 訊息接收者帳戶識別碼 Hive 玩家 ID | 長整數 | Y | 例如 2222 |
message | 要發送的 1:1 訊息 (最多 200 個字符) | 字串 | Y | 例如 "Hello World!" |
extraData | 附加訊息資訊 (UTF-8 基礎)(最多 256 字節) | 字串 | Y | 例如 "bbbb" |
langCode | 發送訊息的語言代碼 Hive 語言代碼 (基於 ISO 639 alpha-2,未被 ISO 639 alpha-2 區分的語言應用 Script 標籤分隔) | 字串 | Y | 例如 "en" |
回應主體¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 對 1:1 訊息傳輸的回應 (RESPONSE_DIRECT_CHAT ) | 字串 | Y |
status | 狀態碼 | 整數 | Y |
message | 狀態訊息 | 字串 | Y |
回應主體 > 主體¶
欄位名稱 | 描述 | 類型 | 必需 | 範例 |
---|---|---|---|---|
status | 回應狀態碼 | 整數 | Y | 例如 200 |
請求範例¶
{
"packetType": "DIRECT_CHAT",
"body": {
"gameIndex": 1,
"from": 2222,
"to": 1234,
"message": "안녕하세요",
"extraData": "bbbb",
"langCode": "ko"
}
}
回應範例¶
插座伺服器事件訊息¶
這描述了當事件發生時,從伺服器發送到客戶端的消息。
這條消息以 packetType NOTIFY
開頭。
頻道條目消息¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 頻道進入消息 (NOTIFY_ENTER_CHANNEL ) | 字串 | Y |
body | 請求數據 | 物件 | Y |
主體¶
欄位名稱 | 描述 | 類型 | 必填 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | 是 | 例如 1 |
channelId | 輸入的頻道 ID | 字串 | 是 | 例如 "open:10" |
playerId | 進入頻道的帳戶識別碼 Hive 玩家 ID | 長整數 | 是 | 例如 1234 |
timestamp | 進入頻道的日期和時間(基於 UTC+0 ,格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ ) | 字串 | 是 | 例如 "2024-11-12T08:59:59.497Z" |
timestampMillis | 進入頻道的日期和時間(Unix 時間戳毫秒) | 長整數 | 是 | 例如 1731401989 |
範例¶
{
"packetType": "NOTIFY_ENTER_CHANNEL",
"body": {
"gameIndex": 1,
"channelId": "open:10",
"playerId": 1234,
"timestamp": "2024-11-12T08:59:59.497Z",
"timestampMillis": 1731401989
}
}
頻道退出消息¶
欄位名稱 | 描述 | 類型 | 是否必填 |
---|---|---|---|
packetType | 通道退出消息 (NOTIFY_EXIT_CHANNEL ) | 字串 | 是 |
body | 請求數據 | 物件 | 是 |
主體¶
欄位名稱 | 描述 | 類型 | 必填 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | Y | 例如 1 |
channelId | 已退出的頻道 ID | 字串 | Y | 例如 "open:10" |
playerId | 從頻道退出的帳戶識別碼 Hive 玩家 ID | 長整數 | Y | 例如 2222 |
timestamp | 從頻道退出的日期和時間(UTC+0 標準,格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ ) | 字串 | Y | 例如 "2024-11-12T08:59:59.497Z" |
timestampMillis | 從頻道退出的日期和時間(UnixTimestamp 毫秒) | 長整數 | Y | 例如 1731401989 |
範例¶
{
"packetType": "NOTIFY_EXIT_CHANNEL",
"body": {
"gameIndex": 1,
"channelId": "open:10",
"playerId": 2222,
"timestamp": "2024-11-12T09:29:35.872Z",
"timestampMillis": 1731401989
}
}
渠道刪除訊息¶
欄位名稱 | 描述 | 類型 | 必需 |
---|---|---|---|
packetType | 頻道刪除消息 (NOTIFY_DELETE_CHANNEL ) | 字串 | 是 |
body | 請求數據 | 物件 | 是 |
內容¶
欄位名稱 | 描述 | 類型 | 必填 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | Y | 例如 1 |
channelId | 已刪除的頻道 ID | 字串 | Y | 例如 "open:10" |
timestamp | 頻道被刪除的日期和時間(基於 UTC+0 ,格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ ) | 字串 | Y | 例如 "2024-11-12T08:59:59.497Z" |
timestampMillis | 頻道被刪除的日期和時間(Unix時間戳毫秒) | 長整數 | Y | 例如 1731401989 |
範例¶
{
"packetType": "NOTIFY_DELETE_CHANNEL",
"body": {
"gameIndex": 1,
"channelId": "owner:1",
"timestamp": "2024-11-13T05:06:29.198Z",
"timestampMillis": 1731401989
}
}
頻道公告訊息¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 通知消息 (NOTIFY_CHANNEL_NOTICE ) | 字串 | Y |
body | 請求數據 | 物件 | Y |
主體¶
欄位名稱 | 描述 | 類型 | 必填 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | Y | 例如 1 |
channelId | 接收通知消息的頻道 ID | 字串 | Y | 例如 "open:10" |
from | 發送通知消息的帳戶識別碼 | 字串 | Y | 例如 SYSTEM |
message | 通知消息的內容 | 字串 | Y | 例如 "這是一條通知消息。" |
timestamp | 發送通知消息的日期和時間(基於 UTC+0 ,格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ ) | 字串 | Y | 例如 "2024-11-13T05:06:29.198Z" |
timestampMillis | 發送通知消息的日期和時間(UnixTimestamp 毫秒) | 長整數 | Y | 例如 1731401989 |
範例¶
// 특정 채널에 공지
{
"packetType": "NOTIFY_CHANNEL_NOTICE",
"body": {
"gameIndex": 1,
"channelId": "open:10",
"from": "SYSTEM",
"message": "공지 메시지 입니다.",
"timestamp": "2024-11-13T05:06:29.198Z",
"timestampMillis": 1731401989
}
}
使用者通知訊息¶
欄位名稱 | 描述 | 類型 | 必需 |
---|---|---|---|
packetType | 用戶通知消息 (NOTIFY_NOTICE ) | 字串 | Y |
body | 請求數據 | 物件 | Y |
主體¶
欄位名稱 | 描述 | 類型 | 必需 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | Y | 例如 1 |
playerId | 接收通知訊息的玩家ID | 長整數 | Y | 例如 123123 |
from | 發送通知訊息的帳戶識別碼 | 字串 | Y | 例如 SYSTEM |
message | 通知訊息的內容 | 字串 | Y | 例如 "這是一條通知訊息。" |
timestamp | 發送通知訊息的日期和時間(基於 UTC+0 ,格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ ) | 字串 | Y | 例如 "2024-11-13T05:06:29.198Z" |
timestampMillis | 發送通知訊息的日期和時間(Unix時間戳毫秒) | 長整數 | Y | 例如 1731401989 |
範例¶
// Notice message for a specific user
{
"packetType": "NOTIFY_NOTICE",
"body": {
"gameIndex": 1,
"playerId": 123123,
"from": "SYSTEM",
"message": "공지 메시지 입니다.",
"timestamp": "2024-11-13T05:06:29.198Z",
"timestampMillis": 1731401989
}
}
頻道消息¶
欄位名稱 | 描述 | 類型 | 必需 |
---|---|---|---|
packetType | 通道消息 (NOTIFY_CHANNEL_CHAT ) | 字串 | 是 |
body | 請求數據 | 物件 | 是 |
主體¶
欄位名稱 | 描述 | 類型 | 必需 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | Y | 例如 1 |
from | 發送頻道消息的帳戶識別碼 Hive 玩家 ID | 長整數 | Y | 例如 2222 |
to | 發送頻道消息的頻道 ID | 字串 | Y | 例如 "open:10" |
message | 頻道消息的內容 | 字串 | Y | 例如 "你好。這是一個頻道聊天。" |
extraData | 消息的附加信息(UTF-8 基礎)(最大 256 字節) | 字串 | Y | 例如 "bbbb" |
timestamp | 發送頻道消息的日期和時間(UTC+0 基礎,格式 yyyy-MM-dd'T'HH:mm:ss.SSSZ ) | 字串 | Y | 例如 "2024-11-13T05:12:18.385Z" |
timestampMillis | 發送頻道消息的日期和時間(UnixTimestamp 毫秒) | 長整數 | Y | 例如 1731401989 |
範例¶
{
"packetType": "NOTIFY_CHANNEL_CHAT",
"body": {
"gameIndex": 1,
"from": 2222,
"to": "open:10",
"message": "Hello World!",
"extraData": "bbbb",
"timestamp": "2024-11-13T05:12:18.385Z",
"timestampMillis": 1731401989
}
}
1:1 訊息¶
欄位名稱 | 描述 | 類型 | 必填 |
---|---|---|---|
packetType | 1:1 訊息 (NOTIFY_DIRECT_CHAT ) | 字串 | 是 |
body | 請求資料 | 物件 | 是 |
主體¶
欄位名稱 | 描述 | 類型 | 必需 | 範例 |
---|---|---|---|---|
gameIndex | Hive 遊戲索引 | 整數 | Y | 例如 1 |
from | 1:1 訊息發送者帳戶識別碼 Hive 玩家 ID | 長整數 | Y | 例如 1234 |
to | 1:1 訊息接收者帳戶識別碼 Hive 玩家 ID | 長整數 | Y | 例如 2222 |
message | 1:1 訊息內容 | 字串 | Y | 例如 "你好。這是一對一的聊天。" |
extraData | 附加訊息資訊(UTF-8 基礎)(最大 256 字節) | 字串 | Y | 例如 "abcd" |
timestamp | 1:1 訊息發送日期和時間(UTC+0 基礎,yyyy-MM-dd'T'HH:mm:ss.SSSZ 格式) | 字串 | Y | 例如 "2024-11-13T05:12:50.060Z" |
timestampMillis | 1:1 訊息發送日期和時間(UnixTimestamp 毫秒) | 長整數 | Y | 例如 1731401989 |