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
|