跳转至正文

聊天与实时通信 ​

HTTP 负责数据读写,WebSocket 负责实时同步。管理员聊天与业务消息共用连接、身份认证和应用资源。

管理员聊天由扩展完整提供:dawn-server 负责表结构、接口与消息投递,dawn-admin 负责聊天界面与实时客户端。应用注册扩展、执行统一安装后即可使用。

管理员聊天 ​

登录后台即可聊天。顶栏图标打开会话列表,搜索联系人或点击用户名旁的图标发起单聊。聊天窗口支持返回列表、历史消息、未读提醒、已读同步、发送重试与亮暗主题。

聊天按会话成员授权,联系人只提供 ID、用户名、姓名与头像。账号有效性随接口请求与连接心跳检查。

扩展方向 ​

当前提供管理员之间的文本单聊。用户聊天、群聊与智能客服属于后续扩展:

场景扩展内容
用户间聊天接入用户身份域、联系人规则与用户端界面
群聊增加群资料、成员角色、邀请与退群规则
智能客服接入 AI 回复、人工接管、客服分配与会话状态

身份域、会话成员、消息类型和状态为这些场景提供基础。客服接入时可沿用同一会话与消息记录,按状态决定由 AI 或人工回复,保留完整的转接历史;具体业务接口与界面随场景实现。

聊天数据 ​

表职责
chat_conversations会话身份、最后消息与排序
chat_members成员身份与已读位置
chat_messages发送者、内容、状态与请求编号
chat_events待发布事件、租约与重试记录

身份使用 realm + subject,与 WS 的 Principal 一致。单聊标识由双方 ID 排序生成,发送重试复用 UUID request_id,已读位置只向前推进。同一请求编号对应不同内容或会话时返回 409。

消息投递 ​

消息、会话摘要和推送事件在同一事务中提交。提交后通过 Redis 唤醒投递器,由数据库租约协调多实例发布。

投递器每批处理 100 条,空闲时每 30 秒执行一次补偿扫描。采用至少一次投递,客户端按 event_id 或消息 ID 合并。published_at 表示事件已写入消息流,ACK 表示设备处理进度,已读位置表示用户阅读进度。

事件数据
chat.message.created消息表示
chat.read.updated会话、成员身份与已读消息 ID

聊天事件外层 data 为 {event_id,data}。客户端在 ready 或 resync_required 时通过 HTTP 同步,数据库提供完整历史。会话刷新与已读提交合并处理,减少重复请求。

HTTP 接口 ​

方法与路径用途
GET /admin/chat-contacts联系人分页,search 搜索用户名和姓名
POST /admin/chat-conversations提交 user_id 获取或创建单聊
GET /admin/chat-conversations会话分页,meta.unread_total 返回未读总数
GET /admin/chat-conversations/{id}/messages历史消息,使用 page_size、before_id
GET /admin/chat-conversations/{id}/messages/{message_id}单条消息
POST /admin/chat-conversations/{id}/messages提交 request_id、content 发送文本
PUT /admin/chat-conversations/{id}/read-position提交 message_id 更新已读位置

文本上限 4000 字符,每位管理员每分钟最多发送 60 条。历史分页返回 meta.has_more 和下一页的 meta.before_id。

业务 WebSocket ​

在 app/admin/realtime.go 注册处理器,通过 Configure 的 o.Realtime = RegisterRealtime 装配。处理器复用 a.DB、a.Redis、a.Key 与管理员授权。

dawn-simple 的 实时示例 注册 app.greeting,校验 app.realtime_example.view,读取当前管理员的五分钟问候缓存。Key 在 app/constants/key.go 定义,并注册到缓存管理。

扩展入口用途
Hub.Handle注册业务请求,按 request_id 返回 result/error
Hub.Publish、Hub.PublishChannel向身份或频道发布消息
Hub.Ticket、Options.WSValidate签发连接票据、扩展身份验证
Options.WSAuthorize、Hub.Authorize频道订阅授权
Hub.AuthorizeEvent事件投递授权
Hub.Connected、Hub.Disconnected单个物理连接的生命周期

业务使用独立事件名称,框架保留认证、订阅、确认、心跳及响应等控制消息。扩展授权与生命周期回调时,按业务命名空间组合既有规则。处理器继承连接 context,耗时任务交给队列,共享状态存入数据库或 Redis。

多设备分别触发生命周期回调。身份收件流按 realm + subject 寻址,恢复凭证绑定登录会话;恢复范围由 Redis 保留时间与条数决定。

前端调用 ​

ts
import { onBeforeUnmount } from 'vue'
import { realtime, openChat } from '@dawnim/admin'

const stop = realtime.on('order.updated', async ({ data }) => {
  // 按业务数据更新页面
})
onBeforeUnmount(stop)

const result = await realtime.request<{ greeting: string }>('app.greeting')
openChat()

openChat() 打开列表;传入 {id, username, realname?, avatar?} 打开指定管理员单聊。realtime.status.value 提供 closed、connecting、ready 状态。请求支持超时与断连反馈,subscribe/unsubscribe 管理授权频道并在重连后恢复订阅,事件处理完成后再确认消息。