Appearance
聊天室(開發文檔)
最後更新:2026-04-10
📖 功能說明請參考 聊天室
架構
相關檔案
Manager / ViewModel / API(4 個)
| 檔案 | 說明 |
|---|---|
.../STChatView/STChatManager.swift | 聊天 Socket 核心 |
.../STChatView/VM/STChatViewModel.swift | 聊天 ViewModel |
.../STChatView/STChatAPI.swift | 聊天 HTTP API |
.../STChatView/M/STChatMessageModel.swift | 訊息 Model |
基礎路徑:
BBSport/Tab/广场/FullScreenLive/
View — 聊天(11 個)
| 檔案 | 說明 |
|---|---|
.../STChatView/V/STChatView.swift | 聊天主視圖 |
.../STChatView/V/STChatHeaderView.swift | Header |
.../STChatView/V/STChatMarqueeView.swift | 跑馬燈 |
.../STChatView/V/STChatMoreMessageView.swift | 更多訊息 |
.../STChatView/V/STChatQuoteView.swift | 引用回覆 |
.../STChatView/V/STMarqueeLabel.swift | 跑馬燈 Label |
.../ChatInputView/STChatInputView.swift | 聊天輸入框 |
.../ChatInputView/STEmojiView.swift | 表情選擇 |
.../Gift/STGiftListView.swift | 禮物列表 |
.../Gift/STGiftListViewController.swift | 禮物列表 VC |
.../Gift/STGiftInputViewController.swift | 禮物輸入 VC |
基礎路徑:
BBSport/Tab/广场/FullScreenLive/
Cell — 訊息(9 個)
| 檔案 | 說明 |
|---|---|
.../Cell/STTextChatMessageTableViewCell.swift | 文字訊息 |
.../Cell/STImageChatMessageTableViewCell.swift | 圖片訊息 |
.../Cell/STChatOrderShareTableViewCell.swift | 曬單訊息 |
.../Cell/STAutoMessageTableViewCell.swift | 自動訊息 |
.../Cell/STChatMessageBaseTableViewCell.swift | 訊息基底 |
.../Cell/STChatSystemMessageTableViewCell.swift | 系統訊息 |
.../Cell/STGiftMessageTableViewCell.swift | 禮物訊息 |
.../Cell/STReplyChatMessageTableViewCell.swift | 回覆訊息 |
.../Cell/STLiveBetGameMessageTableViewCell.swift | 競猜訊息 |
基礎路徑:
BBSport/Tab/广场/FullScreenLive/STChatView/
禮物排行 / 競猜(6 個)
| 檔案 | 說明 |
|---|---|
.../Gift/GiftRank/STGiftRankView.swift | 禮物排行 |
.../Gift/GiftRank/VM/GiftRankViewModel.swift | 排行 ViewModel |
.../Gift/GiftRank/V/STGiftRankTopThreeView.swift | 前三名 |
.../LiveBetGame/LiveBetGameView.swift | 競猜遊戲 |
.../LiveBetGame/LiveBetGameViewModel.swift | 競猜 ViewModel |
.../LiveBetGame/Cell/LiveBetGameCell.swift | 競猜 Cell |
基礎路徑:
BBSport/Tab/广场/FullScreenLive/
Socket 底層(2 個)
| 檔案 | 說明 |
|---|---|
.../Socket/SocketServices.m | Socket 連線(OC) |
.../Socket/BBSocketServices.m | Socket 管理單例(OC) |
基礎路徑:
BBSport/Tools/UtilityToolComponentOC/Classes/Helper/
API Request(30 個)
| 檔案 | 說明 |
|---|---|
.../STAPI+GetChatTokenRequest.swift | 聊天 Token |
.../STAPI+LiveGiftListRequest.swift | 禮物列表 |
.../STAPI+LiveEmojiListRequest.swift | 表情列表 |
.../STAPI+SendGiftRequest.swift | 送禮物 |
.../STAPI+GetTopRankGiftListRequest.swift | 禮物排行 |
.../STAPI+RedPacketRequest.swift | 紅包狀態 |
.../STAPI+RainRedPacketRequest.swift | 紅包雨狀態 |
.../STAPI+ReceiveRedPacketRequest.swift | 領取紅包 |
.../STAPI+ReceiveRainRedPacketRequest.swift | 領取紅包雨 |
.../STAPI+ChatReportListRequest.swift | 舉報類別 |
.../STAPI+SendChatReportRequest.swift | 送出舉報 |
.../STAPI+GetLiveActivityRequest.swift | 直播活動 |
.../STAPI+LiveActivityJoinRequest.swift | 加入活動 |
.../STAPI+GetVoteInfoRequest.swift | 投票資訊 |
.../STAPI+SubmitVoteInfoRequest.swift | 提交投票 |
.../STAPI+GetApprovalInfoRequest.swift | 支持率資訊 |
.../STAPI+GetPushOrderApprovalInfoRequest.swift | 推單支持率 |
.../STAPI+SubmitApprovalInfoRequest.swift | 提交支持率 |
.../STAPI+LuckyDrawStartInfoRequest.swift | 抽獎資訊 |
.../STAPI+ActivityWinResultRequest.swift | 抽獎結果 |
.../STAPI+ActivityWinUserListRequest.swift | 中獎名單 |
.../STAPI+TurnTableGameInfoRequest.swift | 轉盤資訊 |
.../STAPI+LargeOrderShareConfigRequest.swift | 大額曬單設定 |
.../STAPI+ReportOrderShareRequest.swift | 曬單上報 |
.../STAPI+FetchChatAutoMessageRequest.swift | 自動推訊息 |
.../STAPI+UploadSTWatchManRequest.swift | 上報觀看人 |
.../STAPI+UserEnterAnimationRequest.swift | 進入動畫 |
.../STAPI+HomeChatListRequest.swift | 首頁聊天紀錄 |
.../STAPI+GetLiveBetGameRequest.swift | 骰寶競猜 |
.../STAPI+GetMatchIDLiveStatusRequest.swift | 賽事直播狀態 |
基礎路徑:
BBSport/API/STAPI/Chat/
API
聊天初始化
取得聊天 Token
GET api/forehead/user/chat/token/v2 — urlForm — STAPI.GetChatTokenRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveHostType | Int | ✅ | 主播類型 |
Response:
| 欄位 | 型別 | 說明 |
|---|---|---|
| token | String | 聊天室 Token |
| chatBanInfo | STChatBanInfoModel | 禁言資訊(見下方展開) |
| chatRule | STChatRuleModel | 發言規則(VIP/充值/投注限制,見下方展開) |
| specialChIds | [String] | 特殊頻道(不受限制) |
STChatBanInfoModel(禁言資訊):
| 欄位 | 型別 | 說明 |
|---|---|---|
| banText | String | 禁言提示文字 |
| isBan | Bool | 是否被禁言 |
| isPermission | Bool | 是否有超管權限 |
| ttlConfig | [STChatTTLConfigModel] | 超管禁言配置(id/ttl/unit/value) |
排查「為什麼不能發言」:先看
isBan是否為 true,再看chatRule是否符合條件。
STChatRuleModel(發言規則):
| 欄位 | 型別 | 說明 |
|---|---|---|
| isAvailable | Bool | 規則是否啟用 |
| vipLimitVal | Int | VIP 等級門檻 |
| vipCurrentVal | Int | 使用者當前 VIP 等級 |
| vipLimitIsAccord | Bool | VIP 是否符合要求 |
| vipLimitText | String | VIP 限制說明文字 |
| betLimitRule | STChatBetLimitRuleModel | 投注限制(coin/cond/currentVal/limitIsAccord/limitText/limitVal) |
| rechargeLimitRule | STChatRechargeLimitRuleModel | 充值限制(coin/rechargeCurrentVal/rechargeLimitIsAccord/rechargeLimitText/rechargeLimitVal) |
betLimitRule.cond:0=未設置, 1=並且(投注+充值都要達標), 2=或是(任一達標即可)。
禮物
禮物列表
POST api/forehead/live/load/gift — urlForm — STAPI.LiveGiftListRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| matchType | String | ✅ | "体育" 或 "娱乐" |
Response:
STGiftModel 欄位(16 個)
| 欄位 | 型別 | 說明 |
|---|---|---|
| id | Int | 禮物 ID |
| name | String | 禮物名稱 |
| photoId | String | 禮物圖片 ID |
| fullScreenPhotoId | String | 全螢幕動效圖片 ID |
| amountDouble | Float | 禮物價格(API 欄位 amount) |
| type | Int | 禮物類型(0=現金, 1=金幣) |
| goldAmount | Int | 金幣額度 |
| giftLevel | Int | 禮物級別(0=平庸, 1=普通, 2=全螢幕炫酷)(API 欄位 level) |
| giftDuration | Float | 顯示時間(API 欄位 showDuration) |
| landscape | Bool | 是否橫屏 |
| giftNumber | Int | 禮物數量 |
| userId | String | 使用者 ID |
| userIcon | String | 使用者頭像 |
| userName | String | 使用者名稱 |
| isSelect | Bool | 是否被選中 |
| isBeSelected | Bool | 是否選中 |
表情列表
POST api/forehead/live/emoji/list — urlForm — STAPI.LiveEmojiListRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| matchType | String | ✅ | "体育" 或 "娱乐" |
Response:
| 欄位 | 型別 | 說明 |
|---|---|---|
| emojiGroupList | [STEmojiListModel] | 表情群組列表 |
STEmojiListModel:
| 欄位 | 型別 | 說明 |
|---|---|---|
| emojiList | [STEmojiModel] | 表情列表 |
| imageId | String | 群組圖片 ID |
STEmojiModel(表情):
| 欄位 | 型別 | 說明 |
|---|---|---|
| id | Int | 表情 ID |
| imageId | String | 表情圖片 ID |
| name | String | 彈幕字串(用於顯示名稱) |
| img | String | 表情圖片 URL |
| type | STEmojiType | 0=Normal(內建), 1=Custom(自定義) |
| groupId | Int | 所屬表情組 ID |
| sort | Int | 排序 |
| status | Int | 狀態 |
發送禮物
POST api/forehead/live/submit/gift/present — urlForm — STAPI.SendGiftRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveRoomId | String | ✅ | 直播間 ID |
| giftId | String | ✅ | 禮物 ID |
| giftCount | String | ✅ | 禮物數量 |
Response: 成功 code=1/429。code=300000 金幣不足。
禮物排行榜
POST api/forehead/live/room/gift/top5 — urlForm — STAPI.GetTopRankGiftListRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveRoomId | Int | ✅ | 直播間 ID |
Response:
| 欄位 | 型別 | 說明 |
|---|---|---|
| cashGiftTop5 | [STGiftRankTableCellModel] | 現金禮物前 5 |
| goldGiftTop5 | [STGiftRankTableCellModel] | 金幣禮物前 5 |
STGiftRankTableCellModel:
| 欄位 | 型別 | 說明 |
|---|---|---|
| index | Int | 排名序號 |
| nickName | String | 暱稱 |
| userName | String | 使用者名稱 |
| headUrl | String | 頭像 URL |
| amount | Double | 贈送金額 |
| userTitleId | Int | 使用者稱號 ID |
| userTitle | String | 使用者稱號 |
| userTitleImage | String | 稱號圖片 |
| vipLeve | Int | VIP 等級 |
| customAvatar | Bool | 是否自訂頭像 |
紅包
紅包狀態
POST api/forehead/live/get/room/redEnvelope — urlForm — STAPI.RedPacketRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| LiveRoomId | Int(字串傳送) | ✅ | 直播間 ID |
Response: STRedPacketInfoModel?
紅包雨狀態
POST api/forehead/live/get/room/redEnvelope/template — urlForm — STAPI.RainRedPacketRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveRoomId | Int(字串傳送) | ✅ | 直播間 ID |
| sendRecordId | Int(字串傳送) | 紅包記錄 ID(>0 時才帶入) |
Response: STRedPacketInfoModel?
領取紅包
POST api/forehead/live/submit/receive/redEnvelope — urlForm — STAPI.ReceiveRedPacketRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| LiveRoomId | Int(字串傳送) | ✅ | 直播間 ID |
| sendRecordId | String | ✅ | 紅包記錄 ID |
Response: Double?(領取金額)
領取紅包雨
POST api/forehead/live/submit/receive/redEnvelope/template — urlForm — STAPI.ReceiveRainRedPacketRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveRoomId | Int(字串傳送) | ✅ | 直播間 ID |
| sendRecordId | Int(字串傳送) | ✅ | 紅包記錄 ID |
| catchTimes | Int(字串傳送) | ✅ | 抓取次數 |
Response:
| 欄位 | 型別 | 說明 |
|---|---|---|
| index | Int | 下標 |
| amount | Int | 價值 |
| awardId | Int | 獎品 ID |
| awardType | Int | 獎品類型 |
| count | Int | 獎品數量 |
| awardName | String | 獎品名稱 |
| imgUrl | String | 圖片 URL |
舉報
舉報類別列表
POST api/forehead/live/chat/report/cate — urlForm — STAPI.ChatReportListRequest
無參數。Response: [String]
送出舉報
POST api/forehead/live/chat/report/add — urlForm — STAPI.SendChatReportRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| account / uid / nick | String | ✅ | 舉報者資訊 |
| targetAccount / targetUid / targetNick / targetType | String/Int | ✅ | 被舉報者資訊 |
| cate | String | ✅ | 舉報類別 |
| msgBody / msgTime | String/Int | ✅ | 被舉報訊息 |
| matchId / homeTeam / guestTeam / game | String | ✅ | 賽事資訊 |
Response: 無 data。
活動
活動列表
POST api/forehead/live/activity/select 或 api/forehead/live/match/activity/select — urlForm — STAPI.GetLiveActivityRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveRoomId | Int | ✅ | 直播間 ID(!=0 時用 match 路徑) |
Response:
STChatEventModel 欄位(16 個)
| 欄位 | 型別 | 說明 |
|---|---|---|
| id | Decimal | 記錄 ID |
| activityId | Decimal | 活動 ID |
| activityType | String | 活動類型 |
| matchId | Decimal | 賽事 ID |
| name | String | 活動名稱 |
| introduce | String | 活動介紹 |
| picture | String | 活動圖片地址 |
| entrancePic | String | 入口圖片 |
| h5Url | String | H5 頁面 URL |
| type | String | 1=文字, 2=圖片 |
| clickEffect | Int | 點擊效果(0=無, 1=連結, 2=Popup 大圖, 3=跳 App 頁面) |
| isJoin | String | 是否可參與(顯示參與按鈕) |
| join | String | 參與活動與否 |
| firstJumpWord | String | 第一次報名問候語 |
| secondJumpWord | String | 第二次報名問候語 |
| liveAppConfig | String | App 頁面參數 |
加入活動
POST api/forehead/live/activity/join/record/add — urlForm — STAPI.LiveActivityJoinRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| roomId / activityId / chatRoomId | String | ✅ | 房間/活動/聊天室 ID |
Response: 無 data。
投票 / 支持率
投票資訊
POST api/forehead/live/lottery/vote/info — urlForm — STAPI.GetVoteInfoRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| roomId | Int | ✅ | 房間 ID |
Response: id, status, voteTitle, userVoteResult, optionBody([VoteOption]), displayType, isChange 等
提交投票
POST api/forehead/live/lottery/vote/submitInfo — urlForm — STAPI.SubmitVoteInfoRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| voteResult | String | ✅ | 投票結果 |
| recordId / roomId | Int(字串傳送) | ✅ | 記錄/房間 ID |
Response: 無 data。
支持率資訊
POST api/forehead/live/lottery/approval/info — urlForm — STAPI.GetApprovalInfoRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| roomId | Int(字串傳送) | !=0 時帶入 | |
| matchId | String | 非空且不為 "0" 時帶入 |
Response: sum, homeSum, awaySum, tieSum, home, away, userApprovalResult 等
提交支持率
POST api/forehead/live/lottery/approval/submitInfo — urlForm — STAPI.SubmitApprovalInfoRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| approvalResult | String | ✅ | 投票結果 |
| roomId / matchId / messageId / orderId | 有值時才帶入 |
Response: 無 data。
抽獎 / 轉盤
抽獎資訊
POST api/forehead/live/lottery/startInfo — urlForm — STAPI.LuckyDrawStartInfoRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| matchId | String | ✅ | 賽事 ID |
| hostId | Int | ✅ | 主播 ID |
Response: STLuckDrawModel?
抽獎結果
POST api/forehead/live/lottery/win — urlForm — STAPI.ActivityWinResultRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| lotteryId / userId / lotteryType | Int | ✅ | 抽獎/使用者/類型 |
Response: lotteryId, userId, isWin, awardInfo(STActivityAwardModel)
主播轉盤資訊
POST api/forehead/live/lottery/big/spin/info — urlForm — STAPI.TurnTableGameInfoRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| matchId | String | ✅ | 賽事 ID |
| hostId | Int | ✅ | 主播 ID |
Response: lotteryId, alreadyPrize, bigSpinCountdownTime, achieveRequire, prizePool(JSON) 等
其他
自動推訊息
POST api/forehead/live/match/message/select — urlForm — STAPI.FetchChatAutoMessageRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| matchId / platformId / hostId | String | ✅ | 賽事/平台/主播 ID |
| messageType | String | ✅ | "1"=有主播, "2"=無主播 |
Response:
| 欄位 | 型別 | 說明 |
|---|---|---|
| id | Int | 訊息 ID |
| message | String | 訊息內容 |
| nickname | String | 發送者暱稱 |
| sendTime | String | 發送時間 |
| createTime | Int | 建立時間 |
| isFromSocket | Bool | 是否來自 Socket 推送 |
曬單上報
POST api/forehead/live/showorder/report — urlForm — STAPI.ReportOrderShareRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| masterTeam / guestTeam | String | ✅ | 主/客隊 |
| betAmount / orderId / matchId | String | ✅ | 金額/單號/賽事 |
| chId | String | ✅ | 聊天室 ID |
| hostId / liveUserGroupId | Int | ✅ | 主播/特權 |
| sportBusiness | String | ✅ | 數據源 |
Response: Bool?
上報觀看人
POST api/forehead/live/submit/watch — urlForm — STAPI.UploadSTWatchManRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveRoomId | Int(字串傳送) | ✅ | 直播間 ID |
| matchId | String | 有值時帶入 |
骰寶競猜
POST api/forehead/live-bet-game/rounds/current — JSON — STAPI.GetLiveBetGameRequest
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| liveRoomId | Int | ✅ | 直播間 ID |
Response: odds([Odds]), round(Round?), settings([Setting]), roundBetAmountLimit(Decimal?)
WebSocket
連線架構
連線建立流程
connectToSocket()→ 檢查eventId != "0"且未連線fetchChatData()→ 取公告、禮物、表情、紅包等fetchChatToken()→ 取聊天 TokenopenSocket(withUrlStr:)→ 建立 WebSocket- 連線成功 → 發送
L01訂閱歷史 →enterAnimation()→ 啟動心跳
斷線重連
| 層級 | 機制 | 間隔 |
|---|---|---|
| SocketServices(底層) | 非手動斷線自動重連 | 5 秒 |
| STChatManager(上層) | 關閉後重新走完整流程 | 10 秒 |
| Token 取得 | 內建重試 | 最多 3 次 |
關鍵數字
- 心跳間隔:30 秒(
{"cmd": "ping"}) - 底層重連:5 秒
- 上層重連:10 秒
- Token 重試:最多 3 次
- Token 過期:伺服器推送
E04,客戶端重新取 Token
完整指令列表(18 個)
| Command | 方向 | 說明 |
|---|---|---|
L01 | 發送 | 訂閱歷史訊息 |
L03 | 接收 | 歷史訊息 |
M01 | 雙向 | 即時訊息 |
R03 | 接收 | 被禁言 |
R04 | 接收 | 充值/VIP 不足 |
R05 | 接收 | 發送太快 |
R06 | 接收 | 曬單上限 |
R09 | 接收 | 訪客發言上限 |
G01 | 接收 | 禮物 |
G02 | 接收 | 活動(紅包/投票) |
G04 / G05 | 接收 | 主播推單/撤單 |
G06 | 接收 | 抽獎 |
G07 | 接收 | 中獎結果 |
P02 | 接收 | 使用者進入(歡迎動畫) |
P001 | 接收 | 自動推訊息 |
P003 | 接收 | 骰寶競猜 |
E04 | 接收 | Token 過期 |
ping | 發送 | 心跳 |
L01 訂閱歷史(發送)
json
{
"cmd": "L01",
"data": {
"chId": "fb12345|67",
"isFirst": "1",
"guestTeamId": "fb12345|67guest",
"homeTeamId": "fb12345|67home",
"nick": "暱稱",
"uid": "123456",
"vip": 3,
"token": "chat-token",
"version": "1.0.0",
"platform": 1
}
}chId格式:{gameType.chatIdPrefix}{eventId}|{hostId}(有主播時)
gameType.chatIdPrefix 對照表:
| GameType | chatIdPrefix | 範例 chId |
|---|---|---|
| bbAmuse(娛樂) | yl | yl12345|67 |
| fbSport(FB 體育) | fb | fb12345|67 |
| dbSport(DB 體育) | ob | ob12345|67 |
| upSport(UP 體育) | st | st12345|67 |
| sicBo(骰寶) | st | st12345|67 |
| 其他 | "" | — |
isFirst:首次"1",重連"0"platform:1=iOS, 2=Android, 3=Web
M01 即時訊息(發送)
json
{
"cmd": "M01",
"data": {
"uid": "123456",
"account": "user_account",
"nick": "暱稱",
"chId": "fb12345|67",
"token": "chat-token",
"vip": 3,
"msg": "你好",
"msgType": 1
}
}訊息類型
| 值 | 說明 |
|---|---|
0x01 | 文字 |
0x02 | 圖片/自訂表情 |
0x03 | 富文本 |
0x04 | 回覆 |
0x05 | 曬單 |
0x07 | 自動推送 |
實作重點
- 聊天室切換:
changeChannel()清空訊息 → 更新 ID → 若已連線直接發L01(免斷線重連) - STChatManager 初始化參數:
eventId,hostId,liveRoomId,chatRoomType(.sport/.entertainment),gameType,liveHostType - 禮物級別:0=平庸, 1=普通, 2=全螢幕炫酷
- 禮物類型:0=現金, 1=金幣