# DimSum Chat 核心共享知识 # 版本:1.2.0 | 更新日期:2026-06-10 # 本文件为 AI Agent 提供开发点心应用所需的核心技术知识 # 详细内容请参阅知识库:E:\个人项目\糕\知识库\ ================================================================ 一、系统架构概述 ================================================================ 点心 Chat 是一款直播美化软件。架构如下: 直播平台 → 主程序(弹幕接入)→ WebSocket 广播 → Widget(HTML 应用)→ UI 渲染 主程序通过本地 Web 服务器(EmbedIO,默认端口 13500)提供 HTML 服务, 同时通过 WebSocket(ws://localhost:13500/websocket)将直播间互动数据推送给 Widget。 Widget 通过 dimsum-chat SDK(npm 包)连接 WebSocket 并解析消息。 ================================================================ 二、Widget 目录结构 ================================================================ ``` Widgets/ ← 主程序 Widgets 目录 └── your-widget-name/ ← 必须与 guide.dimsum.json 的 base 一致 ├── guide.dimsum.json ← 必需!配置文件 ├── index.html ← 入口页面 └── ...(其他静态资源) ``` ================================================================ 三、guide.dimsum.json 配置格式(必知) ================================================================ ```json { "name": "应用名称", "version": "1.0.0", "base": "/your-widget-name/", "description": "应用描述", "pages": [ { "name": "弹幕", "path": "index.html", "width": 400, "height": 600, "description": "建议尺寸 400x600。" } ] } ``` 关键规则: - base(必填):必须以 / 开头和结尾,与文件夹名一致 - 命名规范:author-theme-year-type,如 moonmi-icecream-2024-danmaku - 仅使用小写字母、数字、连字符 - pages[].path:HTML 文件路径或查询字符串(如 ?danmu) - pages[].description 含"浏览器中打开"时,该页面会在外部浏览器打开 - 国际化:guide.dimsum.{culture}.json(如 guide.dimsum.zh-CN.json) ================================================================ 四、SDK 核心 API ================================================================ ⚠️ Parser 属性的完整类型声明请以 parser-types.txt 为准! 切勿猜测属性名——错误示例:giftCount(正确是 giftNum)、 userAvatar(正确是 avatar)、giftIcon(正确是 giftImage)。 4.1 CDN 引入(推荐方式) ```html ``` 备选 CDN:https://cdn.jsdelivr.net/npm/dimsum-chat@0/+esm 4.2 onMessage — 核心入口 ```javascript onMessage((msg, parser) => { // msg: 原始消息 { type: string, content: any } // parser: Parser 实例,提供统一的消息属性 }) ``` - 自动连接 WebSocket(无需手动管理连接) - 自动响应 DimSumChatWidgetInfoResponse(无需手动处理) - 可选参数: - `customWsServer`: 自定义 WebSocket 服务器地址(开发调试用) - `widgetNickName` (v0.5.0+): Widget 昵称,用于跨组件通信时标识自身 ```javascript onMessage((msg, parser) => { /* ... */ }, { widgetNickName: '我的弹幕组件' }) ``` 4.3 Parser — 消息解析器核心属性 将各平台原始消息统一为标准属性(完整列表见 parser-types.txt): | 属性 | 类型 | 说明 | |--------------|-----------|---------------------------------------| | type | string | 统一消息类型(见第五节) | | platform | string | 平台标识 | | userName | string | 用户昵称 | | uid | number\|string | 用户 ID | | avatar | string | 头像 URL(注意:是 avatar,不是 userAvatar) | | comment | string | 弹幕文本(type=comment 时) | | giftName | string | 礼物名称(type=gift 时) | | giftNum | number | 礼物数量(注意:是 giftNum,不是 giftCount) | | giftUnitPrice| number | 礼物单价(元,注意:是 giftUnitPrice) | | giftTotalPrice| number | 礼物总价 = giftNum * giftUnitPrice | | giftImage | string | 礼物图片 URL(注意:是 giftImage,不是 giftIcon) | | clubLevel | number | 粉丝团等级 | | guardLevel | 0\|3\|2\|1 | 大航海等级 | | price | number | 便捷价格(自动根据 type 选择) | ⚠️ 不存在这些属性:userAvatar, giftCount, giftPrice, giftIcon, giftCombo, commentEmots, level, isVip, isGuard, roomId, roomName, anchorName, anchorId, timestamp。完整属性列表见 parser-types.txt。 属性缓存:所有属性首次访问时计算并缓存,多次读取无额外开销。 4.4 getCommentHTML(options) 返回含表情图片的 HTML 字符串,已做 XSS 转义,可安全插入 innerHTML: ```javascript const html = parser.getCommentHTML({ stickerStyle: "height:80px;margin:5px;", emotStyle: "height:36px;vertical-align:baseline;", }) element.innerHTML = html // 安全,已转义 ``` 4.5 getBfaceURL(uid) 生成 B 站头像代理 URL(避免 CORS): ```javascript const avatar = parser.platform === 'bilibili' && parser.uid ? getBfaceURL(parser.uid) : parser.avatar // 注意:属性名是 avatar,不是 userAvatar! ``` 4.6 Parser 静态表情映射(v0.5.0+) 无需创建 Parser 实例即可访问各平台表情映射: ```javascript import { Parser } from 'dimsum-chat' // 遍历所有表情关键词→URL Parser.BilibiliEmots.forEach(([emot, url]) => console.log(emot, url)) Parser.DouyinEmots.forEach(([emot, url]) => console.log(emot, url)) Parser.KuaishouEmots.forEach(([emot, url]) => console.log(emot, url)) ``` ================================================================ 五、统一消息类型 ================================================================ | type | 含义 | |-----------|----------| | comment | 弹幕/评论 | | gift | 礼物 | | follow | 关注 | | joinclub | 加入粉丝团 | | like | 点赞 | | guard | 上舰/守护 | | superchat | 超级留言 | | enter | 进入直播间 | | share | 分享 | 使用方式: ```javascript onMessage((msg, parser) => { switch (parser.type) { case 'comment': /* 处理弹幕 */ break case 'gift': /* 处理礼物 */ break case 'like': /* 处理点赞 */ break // ... } }) ``` ================================================================ 六、平台标识 ================================================================ | 平台 | 标识符 | |----------|----------| | Bilibili | bilibili | | 抖音 | douyin | | 快手 | kuaishou | | CHZZK | chzzk | | AcFun | acfun | | OpenBLive| openblive| ================================================================ 七、安全规范(强制) ================================================================ 7.1 XSS 防护 直接插入用户内容到 innerHTML 前必须转义: ```javascript function escapeHtml(text) { const div = document.createElement('div') div.textContent = text return div.innerHTML } ``` 推荐使用 parser.getCommentHTML()(已内置转义)。 7.2 CORS 策略 - HTML 中必须添加: - Widget 必须通过主程序服务器加载(localhost:13500),不能以 file:// 打开 7.3 错误处理 每条消息处理都应包裹 try-catch: ```javascript onMessage((msg, parser) => { try { // 处理消息 } catch (e) { console.error('消息处理失败:', e) } }) ``` ================================================================ 八、打包分发 ================================================================ .ds 文件本质是 ZIP 压缩包,包含所有静态资源。 手动打包步骤: 1. 将项目文件放入以 base 命名的文件夹 2. 压缩为 ZIP(确保 guide.dimsum.json 在根目录) 3. 将 .zip 重命名为 .ds 用户安装:主程序 → 「我的应用」→ 安装 .ds 文件 ================================================================ 九、跨组件通信(v0.5.0+) ================================================================ 9.1 概述 DimSumChatCallMessageRequest 允许在同一主程序内运行的不同 Widget 之间通信。 例如:一个「控制台」页面向「显示层」页面发送指令。 数据流向:Widget A → WebSocket → 主程序服务器 → WebSocket → Widget B 服务器根据 targetNickName 进行消息路由。 Widget 在连接握手时通过 widgetNickName 注册自己的标识。 9.2 设置 Widget 昵称 方式一:onMessage 选项(推荐) ```javascript import { onMessage } from 'dimsum-chat' onMessage((msg, parser) => { // 处理消息 }, { widgetNickName: '我的弹幕组件' // ← 注册昵称 }) ``` 方式二:运行时动态设置 ```javascript import { WebSocketManager } from 'dimsum-chat' const manager = WebSocketManager.getInstance() manager.widgetNickName = '我的弹幕组件' ``` 9.3 发送跨组件消息 通过 `WebSocketManager.send()` 发送 DimSumChatCallMessageRequest(v0.5.1+): ```javascript import { WebSocketManager } from 'dimsum-chat' /** * 发送跨组件消息 * @param targetNickName - 目标 Widget 的昵称 * @param action - 操作名称 * @param params - 可选参数对象 */ function sendToWidget(targetNickName, action, params = {}) { const ws = WebSocketManager.getInstance() const success = ws.send({ type: 'DimSumChatCallMessageRequest', content: { targetNickName, requestData: { action, params } } }) if (!success) { console.warn('WebSocket 未连接,无法发送消息') } } ``` > `send()` 方法内部自动执行 JSON.stringify,连接未就绪时静默失败不抛异常。返回 true 表示成功,false 表示连接未就绪。 9.4 接收跨组件消息 所有 Widget 收到的 WebSocket 消息都会经过 onMessage 回调。 跨组件消息会以如下格式到达: ```javascript onMessage((msg, parser) => { if (msg.type === 'DimSumChatCallMessageRequest') { const { requestData } = msg.content // requestData.action — 操作名称 // requestData.params — 参数对象 switch (requestData.action) { case 'showDanmaku': showDanmakuEffect(requestData.params) break case 'updateConfig': updateConfig(requestData.params) break } } }) ``` 注意:`originationNickName` 字段由服务器在转发时自动替换,接收方收到的 content 中的 targetNickName 会被替换为 originationNickName(即发件方的昵称)。 9.5 控制台 + 显示层分离架构示例 guide.dimsum.json: ```json { "name": "我的应用", "base": "/my-app/", "pages": [ { "name": "控制台", "path": "index.html?mode=ctrl", "width": 400, "height": 600 }, { "name": "显示层", "path": "index.html?mode=display", "width": 1920, "height": 1080 } ] } ``` 控制台端(mode=ctrl): ```javascript import { onMessage } from 'dimsum-chat' onMessage((msg, parser) => { /* ... */ }, { widgetNickName: '控制台' }) // 点击按钮时发送指令给显示层 document.getElementById('hide-btn').onclick = () => { WebSocketManager.getInstance().send({ type: 'DimSumChatCallMessageRequest', content: { targetNickName: '显示层', requestData: { action: 'toggleVisibility', params: {} } } }) } ``` 显示层端(mode=display): ```javascript import { onMessage } from 'dimsum-chat' onMessage((msg, parser) => { if (msg.type === 'DimSumChatCallMessageRequest') { const { action } = msg.content.requestData if (action === 'toggleVisibility') { document.body.style.display = document.body.style.display === 'none' ? '' : 'none' } } }, { widgetNickName: '显示层' }) ``` ================================================================ 九、常用键值速查 ================================================================ WebSocket 默认端口:13500 WebSocket 路径:/websocket SDK CDN(国内):https://fastly.jsdelivr.net/npm/dimsum-chat@0/+esm 配置文件名:guide.dimsum.json(必须) 打包后缀:.ds Widget 访问 URL 格式:http://localhost:13500/{base}/index.html npm 包名:dimsum-chat npm 版本:0.5.1