Pawcast v0.2 · catclaw migration

直播监控

本页 v0.2 · 已按 catclaw 真实代码完整重写。核心机制:30s 调度器 + 90s 连接 backoff + 10 分钟 session 复用 + 5 次指数退避自动重连 + 24 种 WebCast 事件类型映射。每场开播自动记录一行 live_session,事件流入 live_events 实时聚合统计。

v0.2 · catclaw 1:1 24 事件类型 每场一行 session 8 屏 + 4 弹窗
00 · MECHANISM

核心机制(与 catclaw 1:1)

监控的本质是「调度器 + 连接器 + 录制器」三元组。代码源自 live-scan-scheduler.ts + live-monitor.ts (678 行)

1️⃣ Scheduler 调度器

每 30s 触发
setInterval(() => runOnce(), 30000)
  1. 查询所有 auto_monitor=1 的 room_meta
  2. 过滤已连接的(connected.has(username)
  3. 检查 90s backoff:距上次尝试 ≥ 90s 才允许重连(防窗口风暴)
  4. 更新 status='连接中' + last_connect_attempt_at
  5. 调用 liveMonitor.connectRoom(username)
  6. 成功 → status='监听中' / 离线 → '待开播' / 错误 → '连接失败'
降级策略:不走 HTTP fetchRoomInfo(不可靠),直接尝试 WS 连接 = LIVE。

2️⃣ RoomConnection 连接器

tiktok-live-connector
每个直播间一个 worker thread,避免阻塞主进程。
  1. 建立 WebSocket 连接到 TikTok WebCast 协议
  2. 订阅 24 种事件类型(见下表)
  3. 事件到达 → extractUserFields() → 标准化 → 派发
  4. 断开 → 5 次指数退避重连(3s, 6s, 12s, 24s, 48s)
  5. 5 次失败 → close session
⚠ 签名问题:TikTok WS 需要 X-Bogus 等签名。catclaw 用 Electron hidden BrowserWindow 抓签名注入到 connector。

3️⃣ Session 复用机制

10 分钟窗口
连接成功后查询 live_sessions 表,10 分钟内同 room_id + username 的已结束 session 直接复用。
SELECT id FROM live_sessions
WHERE room_id = ? AND streamer_username = ?
  AND disconnected_at IS NOT NULL
  AND disconnected_at > (now - 600000)
ORDER BY disconnected_at DESC LIMIT 1
意义:主播短暂掉线(< 10 分钟)重连,数据继续累计到同一场,不会拆成两场虚假记录。

4️⃣ 事件流持久化

live_events 表
每个事件 → incrementSessionStats() 实时更新聚合 + insert 到 live_events。
UPDATE live_sessions SET
  total_events = total_events + 1,
  total_chat = ...,
  total_gift_value = total_gift_value + (?*?),
  peak_viewers = MAX(peak_viewers, ?)
WHERE id = ?
session 结束时再次 updateLiveSessionStats() 全量重算(含 avg_viewers / duration / diamond_per_hour)。

24 种 WebCast 事件类型映射

EVENT_MAP · live-monitor.ts:79-121
WebcastChatMessagechat
WebcastGiftMessagegift
WebcastMemberMessagemember
WebcastLikeMessage
WebcastSocialMessage
WebcastSubNotifyMsgsub
WebcastQuestionNewqNew
WebcastRoomMessageroomInfo
RoomUserSeqMsgroomUsr
GoalUpdateMsggoal
CaptionMsgcaption
ImDeleteMsgimDel
EnvelopeMsgenvelope
RankUpdateMsgrank
RankTextMsgrankT
LiveIntroMsgintro
PollMsgpoll
DetectMsgdetect
LinkMicBattlebattle
LinkMicArmiesarmies
ControlMsg(end)live_end
(internal) connectedconn
(internal) disconnecteddisc
SubscriptionMsgsub2
01 · GRID

主监控网格 · 5 种状态色

所有 auto_monitor=1 的房间都会出现在网格里。每个 tile 显示当前状态(监听中/连接中/待开播/连接失败/已暂停)+ 实时观众/礼物数字。点击 tile 进入单房详情。

Pawcast · Live Monitor · 主页v0.1.0

监控房间 · 9

LIVE 5 待开播 2 连接中 1 失败 1
⏱ 下次巡检 +14s · ✓ 上次扫描 16s 前 · 🔄 连接尝试 4 / 跳过 2(90s backoff)
监听中
Yoochan
@yoochan_kr
监听中🔥 HOT
Link8
@link8_kr
监听中PK
Mochi
@mochi.cat
监听中
Uni
@uni.chuuu
监听中
Zero
@zero_
连接中
Karen
@karen.j
待开播
Bubbloom
@bubbloom.jp
待开播
Sonna
@s0nna_a
连接失败
Hana
@hana.live

调度器健康

巡检间隔30s
连接 backoff90s
本次扫描时长1.84s
上次成功率5/6 = 83%
总连接尝试142
总成功128
运行时长14h 22m

实时事件流

最近 50 条
21:30:14battleMochi 进入 PK
21:29:58giftYoochan ← Galaxy ¥150
21:29:52chatLink8 ← @taro_pop
21:29:45Mira +3 关注
21:29:12live_endBubbloom 下播
21:28:40memberLink8 观众破 8K
21:28:22Yoochan +280 赞
21:28:02battleMochi PK 胜场
21:27:24⚠ alertLink8 速率破 540/min
5 种 tile 状态监听中(红心跳)/ 连接中(黄色 spinner)/ 待开播(紫虚线)/ 连接失败(红边框)/ 已暂停。颜色对应 catclaw monitor_status 字段。
HOT 标识礼物速率突破阈值(默认 500/min 持续 3 分钟)→ 卡片背景变橙红 + HOT 标识。AlertEngine 自动判定。
session 编号 + 时长每个 LIVE tile 底部显示 session #851 · 2h 14m,对应 live_sessions.id + duration_sec。
调度器健康右侧栏实时显示巡检状态。让运营知道系统在工作。"上次成功率 5/6" 一目了然知道哪个房间有连接问题。
实时事件流所有 24 种事件类型按 emoji + 颜色 pill 区分。Bloomberg 终端式滚动。点击单条可跳到对应房间详情。
实现说明每 LIVE 房间一个 worker thread + WebSocket,事件 → IPC → zustand store → React re-render。30 秒巡检在主进程跑(轻量 SQL 查询不影响 worker)。
状态切换实例「待开播 → 连接中」:Scheduler 检测到 90s backoff 已过,调用 connectRoom。「连接中 → 监听中」:WebSocket onopen + 收到第一个 RoomMessage。
02 · DETAIL

单房间详情 · session 列表 + 事件 + 礼物排行

点击 tile 进入。左侧是房间元信息 + 当前 session 实时数据。右侧是历史 sessions(每场一行)+ Top Gifters + 24 事件类型筛选。

Pawcast · Live Monitor / @link8_krv0.1.0
L
Link8
@link8_kr · session #851 (active)
监听中

当前 session 聚合统计

实时
peak_viewers
8,432
avg_viewers
5,180
total_gift_value
28,450
total_chat
1,247
total_gift_count
340
duration_sec
8,084
diamond_per_hour(核心 KPI)
12,673

历史 sessions · 最近 10 场

#开播时长峰值礼物币钻/小时
#85121:142h 14m8,43228,45012,673
#84704-29 21:002h 28m7,84022,1808,932
#84204-28 20:483h 02m9,12035,42011,652
#83804-27 21:121h 56m5,42014,8207,659
事件流 Top Gifters 礼物排行 送礼者档案
全部 24 类 gift 340 chat 1247 like 47 member 84 follow 12 battle 3
21:30:14 battle LinkMicBattleMessage start · vs @teamx_lia
21:30:08 gift @taro_pop ← Galaxy ×1 (¥150) · 粉丝等级 12
21:29:58 chat @silent_fan_42: 太精彩了!
21:29:50 @kawaii_jin 关注了主播
21:29:45 member @uchan_ 进入直播间
21:29:42 gift @kawaii_jin ← Cake ×8 (¥2,480) · 粉丝等级 18
21:29:36 +82 赞 · 累计 8,432
21:29:30 sub @vip_user 订阅了 Tier 1
21:29:24 rank @taro_pop 升上 Top 1(贡献 12,450)
聚合统计字段来自 live_sessions 表实时累计 + 重算。diamond_per_hour = total_gift_value × 3600 / duration_sec,是核心 KPI。
历史 sessions 表每场一行,按 connected_at desc 排。点击 row 进入历史回放(Phase 7 后期实装)。
24 事件筛选顶部 chip 按事件类型过滤。可多选叠加。
事件详情含完整 user 字段(粉丝等级 / 关注状态 / 角色等),来自 extractUserFields()
性能事件流虚拟滚动,10 万条记录依然 60fps。SQL 用 (session_id) 索引秒级查询。
03 · ADD + CONFIG

添加房间 + 调度器配置

关键弹窗:① 添加房间到 room_meta 表 ② 调度器全局配置(巡检间隔 / backoff / 并发上限)。

添加流程① 写入 room_meta 表 ② 调度器下次 tick 自动尝试 ③ 用户也可手动点"立即尝试"绕过 90s backoff。
auto_monitor 开关临时禁用某房间不删除(保留 group / notes 等元数据)。
验证添加前调用 fetch('https://www.tiktok.com/@username') 确认 username 真实存在,避免脏数据。
5 个调度器参数都来自 catclaw live-scan-scheduler.ts + live-monitor.ts 的真实常量。改这些 = 改运行时行为。
默认值30s / 90s / 16 / 600s / 5 次都是生产验证过最优值,普通用户不需修改。
立即生效保存后通过 IPC 推到 LiveScheduler / LiveMonitorManager 实例,下次 tick 应用新参数。无需重启。
04 · PK BATTLE

PK 战役详情(事件来自 LinkMicBattle / LinkMicArmies)

PK 战役在事件流中通过 WebcastLinkMicBattle + WebcastLinkMicArmies 触发。注:catclaw 的 EVENT_MAP 已映射,但主动写入 pk_battles 表的逻辑未实装,本 phase 在 Pawcast 补完。

事件源WebcastLinkMicBattle 携带 battle_id / 对手 user_id / 起始时间。WebcastLinkMicArmies 携带每方观众阵营 + 实时积分。
胜负判定战役结束时携带 winner_user_id(与 my_streamer.user_id 比对决定胜负)。catclaw 事件已收但未写入 pk_battles。
本 phase 补缺口新建 PKCollector 类,订阅这两个事件 → 解析 → 写 pk_battles 表 → IPC 推 PKDetailModal。
05 · HISTORY

历史数据回看 · 切换实时 / 历史

监控主页顶部「实时 / 历史」切换 chip。切到历史后,房间网格变成日期列表 + 每场 session 卡片,可按主播 / 日期 / 时长 / 礼物币 / PK 状态筛选。点单场进入回放页(事件 timeline + 重算 KPI)。

Pawcast · Live Monitor / 历史 sessionsv0.1.0

日期范围

起始日期
截止日期

主播筛选

属性筛选

时长
礼物币
含 PK 战役
仅看含 PK 的场次
含告警
仅看触发过告警的
总场次
142
总时长
328h
总礼物币
2.4M
峰值观众
12,840
PK 战役
38

礼物币趋势 · 30 天

按日聚合
04-0204-1505-02
142 场 sessions
# 主播 开播时间 时长 峰值观众 礼物币 钻/小时 PK
#851
LLink8 🔥
05-02 21:14 2h 14m 8,432 28,450 12,673
#849
MMochi
05-02 20:32 1h 02m 2,840 8,120 7,860 3 胜 1 负
#847
YYoochan
05-01 21:00 2h 28m 7,840 22,180 8,932
#842
LLink8
04-30 20:48 3h 02m 9,120 35,420 11,652 1 负
#838
UUni
04-30 19:12 1h 56m 5,420 14,820 7,659 2 胜
#834
MMochi
04-29 21:08 1h 38m 2,180 6,440 3,932
显示 6 / 共 142 场 · 加载更多
实时 / 历史切换顶部 chip。实时 = 当前 LIVE 房间网格;历史 = 所有 live_sessions 表的记录列表。
多维度筛选日期范围 + 主播多选 + 时长 / 礼物币 / 含 PK / 含告警。所有过滤都走 SQLite 索引快查。
5 卡总览统计选定区间内:总场次 / 总时长 / 总礼物币 / 峰值观众 / PK 战役数。一目了然。
30 天礼物币趋势按日聚合柱图,看哪天哪个时段最爆。
排序 + 表格视图默认按钻/小时降序(核心 KPI)。可切卡片视图(每场显示缩略 hero)。
每场点回放进入历史回放页(下一屏):事件 timeline + 重算 KPI + 礼物排行。
实现说明list 用 react-window 虚拟滚动。SQL 用 connected_at 索引按日期范围分页。趋势图用 SELECT date(connected_at), SUM(total_gift_value) GROUP BY date(...) 聚合。
Pawcast · Live Monitor / 回放 #851 · Link8v0.1.0
← 返回历史列表 L
Link8 · session #851
2026-05-02 21:14 → 23:28 · 时长 2h 14m
已结束
peak_viewers
8,432
avg_viewers
5,180
钻 / 小时(核心 KPI)
12,673
total_gifts
28,450
total_chat
1,247

礼物排行

🌌 Galaxy×2412,000
🎂 Cake×848,440
🌹 Rose×1563,120
💖 Heart Me×9802,940
🍦 Ice Cream×1861,950

Top 5 送礼者

1T@taro_pop12,450
2K@kawaii_jin5,840
3S@silent_fan_423,820
4U@uchan_2,480
5M@mochi_881,860
21:14:00 开播 22:18:24(当前位置) 23:28:00 下播

事件 timeline

共 18,420 条 · 当前 22:18 附近
22:18:24 gift @taro_pop ← Galaxy ×3 (¥450) · 粉丝等级 12
22:18:18 chat @silent_fan_42: 太精彩了!
22:18:12 @kawaii_jin 关注
22:17:48 ⚠ alert 速率突破 540/min · 持续 3 分钟
22:17:32 gift @kawaii_jin ← Cake ×8 (¥2,480)
22:16:40 member 观众破 8K(峰值时刻)
22:15:18 chat @hopecore_fan: cool!
22:15:02 rank @taro_pop 升上 Top 1
22:14:36 +820 赞 · 累计 8,432
顶部 session 头主播 + 时间范围 + 时长 + 已结束标识 + 导出本场 .xlsx 按钮。
左侧 KPI 卡5 个核心字段:peak/avg viewers / total_gifts / total_chat / 钻每小时(突出色块强调)。
礼物排行 + Top 5 送礼者SQL GROUP BY 一次查回。Top 5 卡片让运营快速识别"金主"。
时间轴 scrubber顶部紫橙渐变进度条 + 高峰 marker(橙=大礼物 / 红=告警 / 绿=观众里程碑)。可拖动定位到任意时刻。
播放控制从开始播放或当前位置播放,1x/2x/5x/10x/30x 倍速。让运营快速看完一场 2 小时的录制。
事件 timeline显示当前时间附近的事件流。关键事件(gift / alert / 里程碑)有左侧色条强调。
实现说明事件回放从 live_events 表按 ts 排序读出。倍速通过 setInterval 跳读 N 倍数据。"播放"模式下,UI 数字、礼物排行、Top Gifters 都按当前时间点的累计值实时重算(所以可以"回看"任一时刻的 leaderboard)。