Skip to content

Socket 與推送通知系統

最後更新:2026-04-09


功能說明

App 內部的即時通訊與事件推送系統,包含三大機制:

  1. WebSocket(IFSocketManager):透過 BBSocketServices 與伺服器建立長連線,接收各類即時推送(chId 分流)
  2. STNotify:基於 NotificationCenter 的全域事件廣播,模組間解耦通訊的核心機制
  3. PushEventManager:處理特定伺服器推送事件(進球、主播開播、大額分享),以浮動視窗方式展示

使用者流程

  1. 登入成功後,系統自動建立 WebSocket 長連線
  2. 伺服器推送各類訊息(充值到帳、提款成功、進球通知等)→ App 顯示對應 Toast / 彈窗 / 浮動通知
  3. 進球推送:浮動卡片顯示 5 秒,點擊跳轉賽事詳情
  4. 主播開播:浮動卡片顯示,點擊跳轉直播間
  5. 大額曬單:浮動卡片顯示,點擊查看詳情
  6. 登出後 → 自動取消 WebSocket 訂閱

頁面跳轉

  • 點擊進球推送浮動卡片 → 賽事詳情頁(對應賽事 ID)
  • 點擊主播開播推送 → StreamerViewController(主播直播間)
  • 點擊大額曬單推送 → 大額分享詳情
  • Socket 充值成功(chId 401)→ Toast 通知 + 震動
  • Socket 專屬客服新訊息(chId 460)→ Toast + 點擊跳轉客服

技術視角(開發看這裡)

相關檔案

類型檔案路徑
WebSocket 管理(OC)/Users/user/Work/bbsport-new/BBSport/Tools/UtilityToolComponentOC/Classes/Helper/Socket/IFSocketManager.m
WebSocket 管理 Header/Users/user/Work/bbsport-new/BBSport/Tools/UtilityToolComponentOC/Classes/Helper/Socket/IFSocketManager.h
Socket 服務封裝(OC)/Users/user/Work/bbsport-new/BBSport/Tools/UtilityToolComponentOC/Classes/Helper/Socket/BBSocketServices.m
Socket 服務封裝 Header/Users/user/Work/bbsport-new/BBSport/Tools/UtilityToolComponentOC/Classes/Helper/Socket/BBSocketServices.h
Socket 底層連線(OC)/Users/user/Work/bbsport-new/BBSport/Tools/UtilityToolComponentOC/Classes/Helper/Socket/SocketServices.m
Socket 底層連線 Header/Users/user/Work/bbsport-new/BBSport/Tools/UtilityToolComponentOC/Classes/Helper/Socket/SocketServices.h
推送事件管理/Users/user/Work/bbsport-new/BBSport/Tools/PushEventManager/PushEventManager.swift
進球推送 Model/Users/user/Work/bbsport-new/BBSport/Tools/PushEventManager/GoalPushEvent/GoalPushEventModel.swift
進球推送 View/Users/user/Work/bbsport-new/BBSport/Tools/PushEventManager/GoalPushEvent/GoalPushEventView.swift
主播開播 Model/Users/user/Work/bbsport-new/BBSport/Tools/PushEventManager/StreamerLivePushEvent/StreamerLivePushEventModel.swift
主播開播 View/Users/user/Work/bbsport-new/BBSport/Tools/PushEventManager/StreamerLivePushEvent/StreamerLivePushEventView.swift
大額曬單 Model/Users/user/Work/bbsport-new/BBSport/Tools/PushEventManager/LargeOrderSharePushEvent/LargeOrderSharePushEventModel.swift
大額曬單 View/Users/user/Work/bbsport-new/BBSport/Tools/PushEventManager/LargeOrderSharePushEvent/LargeOrderSharePushEventView.swift
極光推送初始化/Users/user/Work/bbsport-new/BBSport/AppDelegate/AppDelegate+JPPush.swift
極光推送 Header/Users/user/Work/bbsport-new/BBSport/Tools/Push/JPPService.h
STNotify 定義/Users/user/Work/bbsport-new/BBSport/Tools/NotificationManager/STNotifyExtension.swift
日誌上傳(阿里雲 SLS)/Users/user/Work/bbsport-new/BBSport/STUIKit/STFoundation/Utils/LogService/LogServiceManager.swift
API(刪除站內信)/Users/user/Work/bbsport-new/BBSport/API/STAPI/Notice/STAPI+DeleteInboxMessageRequest.swift
API(站內信列表)/Users/user/Work/bbsport-new/BBSport/API/STAPI/Notice/STAPI+InboxNoticeRequest.swift
API(已讀站內信)/Users/user/Work/bbsport-new/BBSport/API/STAPI/Notice/STAPI+ReadInboxMessageRequest.swift
API(已讀通知訊息)/Users/user/Work/bbsport-new/BBSport/API/STAPI/Notice/STAPI+ReadNoticeMessageRequest.swift
API(通知詳情)/Users/user/Work/bbsport-new/BBSport/API/STAPI/Notice/STAPI+UserNoticeInfoDetailRequest.swift
API(通知列表)/Users/user/Work/bbsport-new/BBSport/API/STAPI/Notice/STAPI+UserNoticeRequest.swift
API(未讀通知數量)/Users/user/Work/bbsport-new/BBSport/API/STAPI/Notice/STAPI+UserNoticeUnreadCountRequest.swift

API

WebSocket 通訊不經過 STAPI,由 BBSocketServices 與伺服器直接維護連線,無對外 Endpoint。

資料模型

WebSocket 訊息 JSON 格式

json
{
  "chId": "401",
  "data": {
    "title": "充值成功",
    "content": "您的充值已到帳...",
    ...
  }
}
  • 伺服器推送的訊息以 JSON 字串傳入,chId 為字串型別
  • dataNSDictionary(多數情況),部分 chId(如 452 大額曬單)的 data 為 JSON 字串需二次解析

完整訂閱 chId 清單(42 個)

登入時訂閱:

chId說明處理方式
102足球即時比分存入 socketDict,不在登出時取消
104足球技術統計存入 socketDict,不在登出時取消
204籃球陣容存入 socketDict,不在登出時取消
2301電競列表存入 socketDict,不在登出時取消
401充值成功STPushToast + 震動 + 清除充值取消計數
402提款成功STPushToast + 震動
403用戶遊戲餘額變更存入 socketDict + STNotify.receivedGameBalanceCharge
405上分成功STPushToast + 震動
406轉帳失敗STPushToast + 震動
407充值失敗STPushToast + 震動
408紅利letterType=1:禮物彈窗;其他:STPushToast + 震動
409返水STPushToast + 震動
410提現退回成功STPushToast + 震動
411加幣STPushToast + 震動
412減幣STPushToast + 震動
413提現失敗STPushToast + 震動
414提現退回失敗STPushToast + 震動
424進球/開賽推送PushEventManager.showIfNeeded(.goal) + SLS 日誌
425平台維護狀態更新 GameMaintenanceManager
426紅包通知紅包浮動條顯示
430邀請好友紅包浮動條顯示
431主播中獎STPushToast + 震動
432CTC 充值訂單付款提醒STPushToast + 震動
433CTC 充值訂單付款超時STPushToast + 震動
434CTC 提現訂單付款提醒STPushToast + 震動
435CTC 充值訂單收款超時STPushToast + 震動
436CTC 提現訂單收款提醒STPushToast + 震動
437CTC 提現訂單收款超時STPushToast + 震動
438訂單確認STPushToast + 震動
439彩蛋活動開啟STPushToast + 彩蛋浮動板 + 震動
440彩蛋活動關閉STPushToast + 震動
441賽事直播開播PushEventManager.showIfNeeded(.streamerLive) + SLS 日誌
442主播直播開播PushEventManager.showIfNeeded(.streamerLive) + SLS 日誌
443C2C 提現訂單超時待撮合STPushToast + 震動
444C2C 提現訂單等待付款STPushToast + 震動
445C2C 提現訂單付款方取消STPushToast + 震動
450直播狀態變更重新取得主播列表 HttpService.fetchAllStreamer
451投票中獎通知STNotify.receivedWinResultPush
452大額曬單PushEventManager.showIfNeeded(.largeOrderShare) + SLS 日誌
453轉盤中獎通知TurnTableGameViewController.showSocketMessage
455關注後可跟單通知STPushToast(含 FollowingUserModel
460專屬客服新訊息CustomerChatManager.checkHaveBoon + STPushToast
462體驗金推送STTrialCoinOverlay 彈窗
514新手轉盤用戶充值/完成加碼STNotify.newUserSpin(過濾非本人 userId)

共 44 個 chId。登出時取消訂閱 37 個(不取消 102/104/204/2301 賽事數據類、441/442 直播類、462 體驗金)。

備註:chId 477(體育賽事陣容開關)雖在訊息處理中出現(存入 socketDict),但不在 subscribeList 中,由其他來源觸發。

PushEventType 枚舉

類型rawValue說明
goal424進球通知
streamerLive442主播開播通知
largeOrderShare452大額訂單分享通知

實作重點

  1. WebSocket 連線管理BBSocketServices.sharedInstance 管理連線,支援重連(reConnected 回調自動重新訂閱)
  2. chId 分流處理IFSocketManager.m 收到訊息後依 chId 字串比對分流,不同 chId 走不同處理邏輯
  3. 訂閱清單:登入時訂閱 44 個 chId,登出時取消訂閱 37 個(賽事數據類 102/104/204/2301、直播類 441/442、體驗金 462 不在取消清單中)
  4. PushEventManager 佇列管理:最多同時顯示 3 個 Push View,每個顯示 5 秒,推送事件有效期 10 秒
  5. 推送事件有效期:10 秒設計是為了避免使用者離開 App 後回來看到過時的推送
  6. 充提類統一處理:chId 401~414 + 431~445 走同一條路(STPushToast + 系統震動),僅 408 紅利和 439 彩蛋有額外邏輯
  7. STNotify 命名慣例:通知名稱使用 camelCase,與功能模組對應(如 userLoginUP → UP 體育登入)
  8. 阿里雲日誌:chId 424/441/442/452 有上傳 SLS 日誌,進球推送每道被攔截的判斷都會記錄原因

API 呼叫流程

WebSocket 連線建立

STChatManager.connectToSocket()
  ├─ [API] GET api/forehead/user/chat/token/v2
  │  → 取得 chatToken 用於 WebSocket 認證

  └─ BBSocketServices.openSocket(url)
     → SocketServices → SRWebSocket 三層架構
     → 連線成功後送出 L01 訂閱訊息

推播通知處理 (PushEventManager)

收到遠端推播 (JPPushDelegate)
  ├─ 解析 userInfo

  ├─ 顯示本地通知 (PushEventManager.showIfNeeded)
  │  ├─ 驗證: 用戶權限、匹配資料來源、非全屏模式、非維護中
  │  ├─ 過期時間: 10 秒
  │  ├─ 最多同時顯示 3 個
  │  └─ 推播類型:
  │     ├─ type 424: 進球推播 → 哨聲 + 震動
  │     ├─ type 442: 主播開播 → 歡呼聲 + 震動
  │     └─ type 452: 大單分享

  └─ 用戶點擊通知 → 路由跳轉
     ├─ type 1: 活動 H5 頁
     ├─ type 2: 賽事詳情
     ├─ type 3: 直播間
     ├─ type 4: 福利中心
     ├─ type 8: 娛樂主播
     ├─ type 9: 福利客服
     └─ type 10: 關注通知

Socket 斷線重連

連線異常 → SocketServices.fl_reconnect
  └─ 等待 5 秒 → 重新 open()
     → 成功 → reConnectedBlock → 重新訂閱