327 lines
8.4 KiB
Markdown
327 lines
8.4 KiB
Markdown
|
|
# CubeWebSocket
|
|||
|
|
|
|||
|
|
一个功能完善的 WebSocket 组件,支持自动连接、重连、消息队列、心跳机制等功能。
|
|||
|
|
|
|||
|
|
## 基础用法
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<div>
|
|||
|
|
<div>状态: {{ status }}</div>
|
|||
|
|
<div>消息数量: {{ messages.length }}</div>
|
|||
|
|
<CubeWebSocket
|
|||
|
|
ws-url="ws://localhost:8086/ws"
|
|||
|
|
:auto-connect="true"
|
|||
|
|
:reconnect="true"
|
|||
|
|
:debug-mode="true"
|
|||
|
|
@connected="handleConnected"
|
|||
|
|
@disconnected="handleDisconnected"
|
|||
|
|
@message="handleMessage"
|
|||
|
|
@status-changed="handleStatusChanged"
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import { ref } from 'vue'
|
|||
|
|
import CubeWebSocket from 'joyd.web.vue.cubelib'
|
|||
|
|
|
|||
|
|
const status = ref('disconnected')
|
|||
|
|
const messages = ref([])
|
|||
|
|
|
|||
|
|
const handleConnected = () => {
|
|||
|
|
console.log('WebSocket 已连接')
|
|||
|
|
status.value = 'connected'
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleDisconnected = (code, reason) => {
|
|||
|
|
console.log('WebSocket 已断开:', code, reason)
|
|||
|
|
status.value = 'disconnected'
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleMessage = (message) => {
|
|||
|
|
console.log('收到消息:', message)
|
|||
|
|
messages.value.push(message)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleStatusChanged = (newStatus) => {
|
|||
|
|
console.log('状态变化:', newStatus)
|
|||
|
|
status.value = newStatus
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Props
|
|||
|
|
|
|||
|
|
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|
|||
|
|
|------|------|------|---------|-------|
|
|||
|
|
| wsUrl | WebSocket 服务器地址 | String | '' | 否 |
|
|||
|
|
| autoConnect | 是否自动连接 | Boolean | true | 否 |
|
|||
|
|
| reconnect | 是否自动重连 | Boolean | true | 否 |
|
|||
|
|
| maxReconnectDelay | 最大重连延迟(毫秒) | Number | 30000 | 否 |
|
|||
|
|
| debugMode | 是否开启调试模式 | Boolean | false | 否 |
|
|||
|
|
| heartbeatInterval | 心跳间隔(毫秒) | Number | 30000 | 否 |
|
|||
|
|
| connectTimeout | 连接超时(毫秒) | Number | 10000 | 否 |
|
|||
|
|
| maxQueueSize | 消息队列最大长度 | Number | 100 | 否 |
|
|||
|
|
|
|||
|
|
### Props 说明
|
|||
|
|
|
|||
|
|
#### wsUrl
|
|||
|
|
WebSocket 服务器的完整 URL 地址。如果为空字符串,则使用默认值 `ws://localhost:8086/ws`。
|
|||
|
|
|
|||
|
|
**验证规则**:如果提供值,必须是有效的 URL 格式。
|
|||
|
|
|
|||
|
|
#### autoConnect
|
|||
|
|
组件挂载时是否自动连接到 WebSocket 服务器。
|
|||
|
|
|
|||
|
|
#### reconnect
|
|||
|
|
连接断开后是否自动重连。重连使用指数退避策略,延迟从 1 秒开始,每次失败后翻倍,最大不超过 `maxReconnectDelay`。
|
|||
|
|
|
|||
|
|
#### maxReconnectDelay
|
|||
|
|
重连的最大延迟时间(毫秒)。默认为 30 秒。
|
|||
|
|
|
|||
|
|
#### debugMode
|
|||
|
|
是否开启调试模式。开启后会在控制台输出详细的日志信息,包括:
|
|||
|
|
- 连接状态变化
|
|||
|
|
- 消息发送和接收
|
|||
|
|
- 错误信息
|
|||
|
|
- 定时器状态
|
|||
|
|
|
|||
|
|
#### heartbeatInterval
|
|||
|
|
心跳检测的间隔时间(毫秒)。连接成功后会定期发送 `ping` 消息以保持连接活跃。
|
|||
|
|
|
|||
|
|
#### connectTimeout
|
|||
|
|
连接超时时间(毫秒)。如果在指定时间内连接未建立,将自动关闭连接并触发 `error` 事件。
|
|||
|
|
|
|||
|
|
#### maxQueueSize
|
|||
|
|
消息队列的最大长度。当连接未建立时,发送的消息会被加入队列。如果队列已满,新消息将被丢弃并触发 `message-failed` 事件。
|
|||
|
|
|
|||
|
|
## Events
|
|||
|
|
|
|||
|
|
| 事件名 | 说明 | 参数 |
|
|||
|
|
|--------|------|------|
|
|||
|
|
| connected | 连接成功 | - |
|
|||
|
|
| disconnected | 连接断开 | (code, reason) |
|
|||
|
|
| error | 连接错误 | error |
|
|||
|
|
| message | 收到消息 | message |
|
|||
|
|
| status-changed | 状态变化 | status |
|
|||
|
|
| connecting | 开始连接 | - |
|
|||
|
|
| reconnecting | 开始重连 | - |
|
|||
|
|
| message-sent | 消息已发送 | message |
|
|||
|
|
| message-queued | 消息已加入队列 | message |
|
|||
|
|
| message-failed | 消息发送失败 | { message, reason, error? } |
|
|||
|
|
|
|||
|
|
### Events 说明
|
|||
|
|
|
|||
|
|
#### connected
|
|||
|
|
WebSocket 连接成功建立时触发。
|
|||
|
|
|
|||
|
|
#### disconnected
|
|||
|
|
WebSocket 连接关闭时触发。参数包括:
|
|||
|
|
- `code`: 关闭代码(数字)
|
|||
|
|
- `reason`: 关闭原因(字符串)
|
|||
|
|
|
|||
|
|
#### error
|
|||
|
|
发生错误时触发。参数为错误对象。
|
|||
|
|
|
|||
|
|
#### message
|
|||
|
|
收到服务器消息时触发。参数为解析后的消息对象。
|
|||
|
|
|
|||
|
|
#### status-changed
|
|||
|
|
连接状态变化时触发。参数为新的状态字符串,可能的值:
|
|||
|
|
- `disconnected`: 未连接
|
|||
|
|
- `connecting`: 连接中
|
|||
|
|
- `connected`: 已连接
|
|||
|
|
- `reconnecting`: 重连中
|
|||
|
|
- `error`: 错误
|
|||
|
|
|
|||
|
|
#### connecting
|
|||
|
|
开始建立连接时触发。
|
|||
|
|
|
|||
|
|
#### reconnecting
|
|||
|
|
开始重连时触发。
|
|||
|
|
|
|||
|
|
#### message-sent
|
|||
|
|
消息成功发送时触发。参数为发送的消息对象。
|
|||
|
|
|
|||
|
|
#### message-queued
|
|||
|
|
消息加入队列时触发(连接未建立时)。参数为消息对象。
|
|||
|
|
|
|||
|
|
#### message-failed
|
|||
|
|
消息发送失败时触发。参数为对象:
|
|||
|
|
- `message`: 失败的消息对象
|
|||
|
|
- `reason`: 失败原因('queue_full' 或 'send_error')
|
|||
|
|
- `error`: 错误对象(仅在 reason 为 'send_error' 时存在)
|
|||
|
|
|
|||
|
|
## Methods
|
|||
|
|
|
|||
|
|
组件通过 `defineExpose` 暴露了以下方法:
|
|||
|
|
|
|||
|
|
| 方法名 | 说明 | 参数 | 返回值 |
|
|||
|
|
|--------|------|------|--------|
|
|||
|
|
| connect | 连接 WebSocket | - | void |
|
|||
|
|
| disconnect | 断开连接 | - | void |
|
|||
|
|
| send | 发送消息 | (type, data) | void |
|
|||
|
|
| reconnect | 手动触发重连 | - | void |
|
|||
|
|
| getStatus | 获取当前状态 | - | string |
|
|||
|
|
| isConnected | 是否已连接 | - | boolean |
|
|||
|
|
| getQueueSize | 获取队列长度 | - | number |
|
|||
|
|
|
|||
|
|
### Methods 说明
|
|||
|
|
|
|||
|
|
#### connect
|
|||
|
|
手动连接到 WebSocket 服务器。如果已经连接或正在连接,则跳过。
|
|||
|
|
|
|||
|
|
#### disconnect
|
|||
|
|
断开 WebSocket 连接并停止所有定时器(心跳、重连等)。
|
|||
|
|
|
|||
|
|
#### send
|
|||
|
|
发送消息到服务器。参数:
|
|||
|
|
- `type`: 消息类型(字符串)
|
|||
|
|
- `data`: 消息数据(对象)
|
|||
|
|
|
|||
|
|
如果连接已建立,消息会立即发送;否则加入队列。
|
|||
|
|
|
|||
|
|
#### reconnect
|
|||
|
|
手动触发重连。通常不需要调用,组件会自动处理重连。
|
|||
|
|
|
|||
|
|
#### getStatus
|
|||
|
|
返回当前连接状态字符串。
|
|||
|
|
|
|||
|
|
#### isConnected
|
|||
|
|
返回布尔值,表示是否已连接。
|
|||
|
|
|
|||
|
|
#### getQueueSize
|
|||
|
|
返回当前消息队列的长度。
|
|||
|
|
|
|||
|
|
## 消息协议
|
|||
|
|
|
|||
|
|
组件使用二进制协议发送和接收消息:
|
|||
|
|
|
|||
|
|
### 发送格式
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
字节 0: 消息类型(0=字符串,1=二进制)
|
|||
|
|
字节 1-2: 扩展参数(2字节,小端序)
|
|||
|
|
字节 3-6: 内容长度(4字节,小端序)
|
|||
|
|
字节 7-N: 内容数据
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
发送的消息会被自动包装为以下格式:
|
|||
|
|
```javascript
|
|||
|
|
{
|
|||
|
|
version: 1, // 协议版本
|
|||
|
|
type: '...', // 消息类型
|
|||
|
|
data: {...} // 消息数据
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 接收格式
|
|||
|
|
|
|||
|
|
组件会自动解析接收到的二进制消息,并触发 `message` 事件。解析后的消息格式与发送格式相同。
|
|||
|
|
|
|||
|
|
## 使用场景
|
|||
|
|
|
|||
|
|
### 场景 1:简单的实时通信
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<script setup>
|
|||
|
|
import CubeWebSocket from 'joyd.web.vue.cubelib'
|
|||
|
|
|
|||
|
|
const wsRef = ref(null)
|
|||
|
|
|
|||
|
|
const sendMessage = () => {
|
|||
|
|
wsRef.value?.send('chat', { text: 'Hello' })
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<CubeWebSocket
|
|||
|
|
ref="wsRef"
|
|||
|
|
ws-url="ws://localhost:8086/ws"
|
|||
|
|
@message="(msg) => console.log(msg)"
|
|||
|
|
/>
|
|||
|
|
<button @click="sendMessage">发送消息</button>
|
|||
|
|
</template>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 场景 2:自动重连和错误处理
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<script setup>
|
|||
|
|
import { ref } from 'vue'
|
|||
|
|
import CubeWebSocket from 'joyd.web.vue.cubelib'
|
|||
|
|
|
|||
|
|
const status = ref('disconnected')
|
|||
|
|
const errorMessage = ref('')
|
|||
|
|
|
|||
|
|
const handleError = (error) => {
|
|||
|
|
errorMessage.value = error.message || '连接错误'
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<div>
|
|||
|
|
<div>状态: {{ status }}</div>
|
|||
|
|
<div v-if="errorMessage" class="error">{{ errorMessage }}</div>
|
|||
|
|
<CubeWebSocket
|
|||
|
|
ws-url="ws://localhost:8086/ws"
|
|||
|
|
:reconnect="true"
|
|||
|
|
@status-changed="status = $event"
|
|||
|
|
@error="handleError"
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 场景 3:消息队列监控
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<script setup>
|
|||
|
|
import { ref, watch } from 'vue'
|
|||
|
|
import CubeWebSocket from 'joyd.web.vue.cubelib'
|
|||
|
|
|
|||
|
|
const wsRef = ref(null)
|
|||
|
|
const queueSize = ref(0)
|
|||
|
|
|
|||
|
|
watch(queueSize, (newSize) => {
|
|||
|
|
if (newSize > 50) {
|
|||
|
|
console.warn('消息队列积压:', newSize)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<div>
|
|||
|
|
<div>队列大小: {{ queueSize }}</div>
|
|||
|
|
<CubeWebSocket
|
|||
|
|
ref="wsRef"
|
|||
|
|
ws-url="ws://localhost:8086/ws"
|
|||
|
|
@message-queued="queueSize++"
|
|||
|
|
@message-sent="queueSize--"
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
1. **URL 格式**:确保 `wsUrl` 是有效的 WebSocket URL 格式(`ws://` 或 `wss://` 开头)
|
|||
|
|
2. **调试模式**:生产环境建议关闭 `debugMode` 以避免日志泄露
|
|||
|
|
3. **消息队列**:队列大小受 `maxQueueSize` 限制,超出部分会被丢弃
|
|||
|
|
4. **心跳机制**:心跳会定期发送 `ping` 消息,确保服务器端不会因超时断开连接
|
|||
|
|
5. **重连策略**:使用指数退避,避免频繁重连造成服务器压力
|
|||
|
|
6. **组件清理**:组件卸载时会自动断开连接并清理所有定时器
|
|||
|
|
|
|||
|
|
## 兼容性
|
|||
|
|
|
|||
|
|
- Chrome >= 16
|
|||
|
|
- Firefox >= 11
|
|||
|
|
- Safari >= 7
|
|||
|
|
- Edge >= 12
|
|||
|
|
- IE >= 10
|
|||
|
|
|
|||
|
|
## 许可证
|
|||
|
|
|
|||
|
|
MIT
|