更新websocket功能

This commit is contained in:
2026-02-18 18:05:33 +08:00
parent e679a9402f
commit a0c2350662
9 changed files with 1273 additions and 74 deletions

444
docs/WEBSOCKET_FEATURE.md Normal file
View File

@@ -0,0 +1,444 @@
# WebSocket 功能文档
## 概述
本系统使用 WebSocket 实现实时通信功能,支持消息推送、数据更新通知等实时功能。
## 技术栈
- **前端**: 原生 WebSocket API + Vue 3 Composable
- **后端**: Laravel-S (Swoole) WebSocket Server
- **协议**: WS/WSS
## 功能特性
### 1. 自动连接管理
- 登录后自动建立 WebSocket 连接
- 用户信息加载完成后自动重试连接
- 支持断线自动重连(最多 5 次)
- 退出登录时自动关闭连接
### 2. 消息推送
- 系统通知推送
- 数据更新通知
- 字典数据更新通知
- 任务提醒
### 3. 心跳机制
- 客户端每 30 秒发送心跳
- 保持连接活跃状态
- 检测连接状态
### 4. 消息管理
- 消息持久化存储localStorage
- 未读消息计数
- 消息分类筛选
- 消息分页显示
- 标记已读/删除消息
## 前端使用
### 1. 在组件中使用 WebSocket
```javascript
import { useWebSocket } from '@/composables/useWebSocket'
const { initWebSocket, closeWebSocket, isConnected, send } = useWebSocket()
// 初始化连接
onMounted(() => {
initWebSocket()
})
// 检查连接状态
if (isConnected()) {
console.log('WebSocket 已连接')
}
// 发送消息
send('message_type', { data: 'your data' })
// 关闭连接
onUnmounted(() => {
closeWebSocket()
})
```
### 2. 在 App.vue 中自动初始化
WebSocket 已在 App.vue 中自动集成,无需手动调用:
- 监听用户信息变化,自动初始化连接
- 组件卸载时自动关闭连接
- 消息数据自动恢复
### 3. 使用消息 Store
```javascript
import { useMessageStore } from '@/stores/modules/message'
const messageStore = useMessageStore()
// 添加消息
messageStore.addMessage({
type: 'notification',
title: '系统通知',
content: '这是一条通知'
})
// 标记已读
messageStore.markAsRead(messageId)
// 标记所有已读
messageStore.markAllAsRead()
// 删除消息
messageStore.removeMessage(messageId)
// 清空所有消息
messageStore.clearAll()
// 获取消息列表(分页)
const { list, total, page } = messageStore.getMessages({
page: 1,
pageSize: 10,
type: 'notification' // 可选:按类型过滤
})
// 格式化消息时间
const timeStr = messageStore.formatMessageTime(timestamp)
```
## 消息类型
### 支持的消息类型
| 类型 | 说明 | 枚举值 |
|------|------|--------|
| 系统通知 | 系统级别的通知消息 | `notification` |
| 任务提醒 | 任务相关提醒 | `task` |
| 警告消息 | 警告类消息 | `warning` |
| 错误消息 | 错误类消息 | `error` |
| 成功消息 | 成功类消息 | `success` |
| 信息消息 | 一般信息 | `info` |
### 消息优先级
| 优先级 | 说明 | 枚举值 |
|--------|------|--------|
| 低 | 低优先级消息 | `low` |
| 中 | 中等优先级消息 | `medium` |
| 高 | 高优先级消息 | `high` |
| 紧急 | 紧急消息 | `urgent` |
## WebSocket 消息格式
### 客户端发送格式
```json
{
"type": "message_type",
"data": {
"key": "value"
}
}
```
### 服务端推送格式
```json
{
"type": "notification",
"data": {
"title": "消息标题",
"content": "消息内容",
"type": "success",
"timestamp": 1234567890
}
}
```
### 数据更新消息格式
```json
{
"type": "data_update",
"data": {
"resource_type": "dictionary",
"action": "update",
"data": {},
"timestamp": 1234567890
}
}
```
## 后端使用
### 1. 发送消息给特定用户
```php
use App\Services\WebSocket\WebSocketService;
$wsService = app(WebSocketService::class);
// 发送给单个用户
$wsService->sendToUser($userId, [
'type' => 'notification',
'data' => [
'title' => '系统通知',
'content' => '这是一条通知',
'type' => 'info',
'timestamp' => time()
]
]);
// 发送给多个用户
$userIds = [1, 2, 3];
$sentTo = $wsService->sendToUsers($userIds, $data);
```
### 2. 广播消息
```php
// 广播给所有在线用户
$count = $wsService->broadcast([
'type' => 'notification',
'data' => [
'title' => '系统维护通知',
'content' => '系统将在 10 分钟后进行维护',
'type' => 'warning',
'timestamp' => time()
]
]);
// 广播给所有在线用户(排除指定用户)
$count = $wsService->broadcast($data, $excludeUserId);
```
### 3. 发送系统通知
```php
// 发送系统通知
$count = $wsService->sendSystemNotification(
'新版本发布',
'系统已更新到 v2.0',
'success'
);
// 发送通知给特定用户
$count = $wsService->sendNotificationToUsers(
[1, 2, 3],
'任务分配',
'您有新的待处理任务',
'task'
);
```
### 4. 发送数据更新通知
```php
// 发送数据更新给特定用户
$userIds = [1, 2, 3];
$sentTo = $wsService->pushDataUpdate(
$userIds,
'dictionary',
'update',
['id' => 1, 'name' => 'test']
);
// 发送数据更新到频道
$count = $wsService->pushDataUpdateToChannel(
'system_admin',
'user',
'create',
['id' => 10, 'username' => 'newuser']
);
```
### 5. 检查用户在线状态
```php
// 检查用户是否在线
$isOnline = $wsService->isUserOnline($userId);
// 获取在线用户数量
$count = $wsService->getOnlineUserCount();
// 获取所有在线用户 ID
$userIds = $wsService->getOnlineUserIds();
// 强制断开用户连接
$wsService->disconnectUser($userId);
```
## 顶部消息组件
### 功能说明
顶部消息组件位于 `layouts/components/userbar.vue`,提供以下功能:
1. **消息通知铃铛**
- 显示未读消息数量
- 点击打开消息列表
2. **消息列表**
- 按类型筛选消息(全部/通知/任务/警告)
- 显示消息标题、内容、时间
- 点击消息标记为已读
- 悬浮显示删除按钮
- 分页浏览
3. **操作按钮**
- 全部标为已读
- 清空全部消息
### 消息样式
- **未读消息**: 蓝色背景 + 左侧蓝条 + 红点标记
- **已读消息**: 普通样式
- **删除按钮**: 悬浮时显示
## 配置说明
### WebSocket URL 配置
`resources/admin/src/config/index.js` 中配置:
```javascript
export default {
// WebSocket URL如果不配置则使用当前域名
WS_URL: 'ws://localhost:8080',
// 其他配置...
}
```
### 后端 WebSocket 配置
`config/laravels.php` 中配置:
```php
'swoole' => [
'enable_coroutine' => true,
'worker_num' => 4,
'max_request' => 5000,
'max_request_grace' => 500,
// ... 其他配置
]
```
## 故障排查
### 1. WebSocket 连接失败
**可能原因**:
- WebSocket 服务未启动
- 端口被占用
- 防火墙阻止连接
- URL 配置错误
**解决方法**:
```bash
# 检查 Laravel-S 是否运行
php bin/laravels status
# 启动 Laravel-S
php bin/laravels start
# 检查端口是否被占用
netstat -ano | findstr :8080
```
### 2. 登录后 WebSocket 未连接
**可能原因**:
- 用户信息未加载完成
- token 无效
**解决方法**:
- 检查控制台日志
- 确认 `userStore.isUserInfoComplete()` 返回 true
- 查看 `getWebSocket` 调用参数
### 3. 消息未收到
**可能原因**:
- 消息处理器未注册
- 消息类型不匹配
- 网络问题
**解决方法**:
- 检查 `useWebSocket.js` 中的消息处理器注册
- 确认消息类型格式正确
- 查看网络面板 WebSocket 帧
## 开发建议
### 1. 测试 WebSocket 功能
```javascript
// 在浏览器控制台测试
import { useWebSocket } from '@/composables/useWebSocket'
import { useMessageStore } from '@/stores/modules/message'
const { send } = useWebSocket()
const messageStore = useMessageStore()
// 手动添加测试消息
messageStore.addMessage({
type: 'notification',
title: '测试消息',
content: '这是一条测试消息',
timestamp: Date.now()
})
// 发送测试消息到服务器
send('test', { message: 'hello' })
```
### 2. 添加新的消息类型
1. 在 `message.js` store 中添加类型枚举
2. 在 `userbar.vue` 中添加对应的 Tab
3. 在 `i18n` 中添加翻译
4. 在 `useWebSocket.js` 中添加处理逻辑
### 3. 自定义消息处理
```javascript
// 在 useWebSocket.js 中注册自定义处理器
ws.value.on('custom_event', handleCustomEvent)
function handleCustomEvent(data) {
console.log('收到自定义消息:', data)
// 处理逻辑
}
```
## 性能优化
1. **消息限制**: 最多存储 100 条消息,超出后自动删除旧消息
2. **分页加载**: 消息列表使用分页,避免一次性加载过多数据
3. **心跳机制**: 保持连接活跃,减少不必要的重连
4. **延迟加载**: 用户信息加载完成后才初始化连接
## 安全考虑
1. **Token 验证**: WebSocket 连接时发送 token 进行验证
2. **用户隔离**: 每个用户只能接收自己的消息
3. **消息过滤**: 根据权限过滤敏感消息
4. **连接限制**: 限制单个用户的连接数量
## 更新日志
### v1.0.0 (2024-01-18)
- 初始版本
- 实现基础 WebSocket 连接功能
- 实现消息推送和接收
- 实现消息管理 Store
- 实现顶部消息组件
- 支持中英文国际化