封装 WebSocket 类(vue3里)(import axios from 'axios' // 配置axios实例 const service = axios.create({ // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL baseURL: '/api', // `timeout` 指定请求超时的毫秒数(0 表示无超时时间) // 如果请求花费了超过 `timeout` 的时间,请求将被中断 timeout: 3000 // ms毫秒 }) // 请求拦截器 service.interceptors.request.use( config => { // 在发送请求之前做些什么 // 例如,设置token // if (store.getters.token) { // config.headers['X-Token'] = getToken(); // } return config }, error => { // 对请求错误做些什么 console.error('请求配置错误:', error) Promise.reject(error) } ) // 响应拦截器 // 请求接口后返回接口值 service.interceptors.response.use( response => { // 对响应数据做点什么 // 例如,检查服务器返回的状态码 const res = response.data // 接收返回数据,对象集合? console.log(res) if (response.status !== 200) { console.error('请求失败:', response.status) return Promise.reject(new Error('请求失败')) } else { // 这里可以统一处理返回的数据格式 // 比如,如果所有接口都返回了{code: 200, data: {}, msg: ''}这样的结构 // 可以统一处理这个结构,只返回data字段 if (res.code === 1) { return res } else { // 如果有错误,可以抛出一个错误 // eslint-disable-next-line no-undef return Promise.reject(new Error(res.message || 'Error')) } } }, error => { // 对响应错误做点什么 console.error('响应错误:', error) // 例如,根据响应码做不同的处理 if (error.response.status === 401) { // 未授权,跳转到登录页面 // router.push('/login'); } return Promise.reject(error) } ) export default service 类似于)
时间: 2025-04-01 14:16:48 浏览: 51
<think>嗯,用户想了解如何在Vue3中封装一个类似Axios的WebSocket类。首先,我需要回顾一下Axios的封装方式,然后看看WebSocket的封装有什么不同。用户提供的Axios示例里有baseURL、拦截器、请求和响应处理,所以WebSocket的封装可能需要类似的配置和拦截机制。
首先,WebSocket和Axios的工作方式不同,Axios是基于HTTP的请求-响应,而WebSocket是长连接的双向通信。所以封装的时候需要考虑连接管理、消息处理、重连机制等。用户可能希望像Axios一样有拦截器,比如在连接建立前做些什么,或者在收到消息后统一处理数据。
接下来,需要确定封装类的结构。可能需要一个类,包含构造函数,配置选项如url、重连次数、心跳检测等。然后,类似Axios的拦截器,可以定义onOpen、onMessage、onError、onClose等钩子。另外,可能需要自动重连的功能,当连接意外断开时尝试重新连接。
然后,考虑心跳机制,保持连接的活跃。WebSocket有时候会因为闲置而断开,定时发送心跳包可以避免这种情况。需要设置定时器,定期发送ping消息或者服务器要求的心跳数据。
在Vue3中,可能需要将这个类实例化并作为全局服务,类似Axios的实例导出,方便在各个组件中使用。另外,需要处理Vue3的响应式数据,比如在接收到消息时更新组件的状态。
用户可能还关心错误处理和重连策略,比如在连接失败时如何重试,重试的次数和间隔时间。此外,发送消息的方法需要封装成类似Axios的Promise风格,或者使用回调,方便在发送前后处理数据。
最后,要确保代码的健壮性,处理各种异常情况,比如网络断开、服务器错误等,并在拦截器中提供足够的扩展点,让用户可以根据需要自定义处理逻辑。可能还需要在封装类中管理状态,比如当前是否正在连接、是否已连接等,方便组件获取连接状态。
总结一下,封装WebSocket类需要处理连接管理、拦截器、心跳、重连、消息发送与接收,以及错误处理。参考Axios的结构,但根据WebSocket的特性进行调整,确保易用性和可维护性。</think>在 Vue3 中封装 WebSocket 类可以参照以下实现方案,采用类似 axios 的拦截器设计模式。这里给出一个完整的实现示例和分层说明:
```typescript
// websocket.ts
type Interceptor<T> = (value: T) => T | Promise<T>
class WS {
private socket: WebSocket | null = null
private reconnectAttempts = 0
private heartbeatInterval: number | null = null
// 配置项
public options = {
url: '',
maxReconnects: 3,
reconnectInterval: 3000,
heartbeat: 30000 // 心跳间隔
}
// 拦截器
public interceptors = {
send: [] as Interceptor<any>[],
receive: [] as Interceptor<any>[]
}
constructor(options: Partial<typeof this.options> = {}) {
Object.assign(this.options, options)
}
// 连接方法
public connect(): Promise<void> {
return new Promise((resolve, reject) => {
this.socket = new WebSocket(this.options.url)
// 基础事件监听
this.socket.onopen = async (event) => {
this.startHeartbeat()
resolve()
}
this.socket.onmessage = async (event) => {
let data = JSON.parse(event.data)
// 接收拦截器处理
for (const interceptor of this.interceptors.receive) {
data = await interceptor(data)
}
this.handleMessage(data)
}
this.socket.onclose = (event) => {
this.handleClose(event)
}
this.socket.onerror = (error) => {
reject(error)
}
})
}
// 消息处理(可扩展)
private handleMessage(data: any) {
// 默认处理逻辑,可通过继承覆盖
console.log('Received:', data)
}
// 关闭处理
private handleClose(event: CloseEvent) {
this.stopHeartbeat()
if (!event.wasClean && this.reconnectAttempts < this.options.maxReconnects) {
setTimeout(() => {
this.reconnectAttempts++
this.connect()
}, this.options.reconnectInterval)
}
}
// 心跳机制
private startHeartbeat() {
this.heartbeatInterval = window.setInterval(() => {
this.send({ type: 'ping' })
}, this.options.heartbeat)
}
private stopHeartbeat() {
if (this.heartbeatInterval) {
clearInterval(this.heartbeatInterval)
}
}
// 发送消息
public async send(data: any): Promise<void> {
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
throw new Error('WebSocket is not connected')
}
// 发送拦截器处理
for (const interceptor of this.interceptors.send) {
data = await interceptor(data)
}
this.socket.send(JSON.stringify(data))
}
// 关闭连接
public close(code?: number, reason?: string) {
this.socket?.close(code, reason)
}
}
// 创建实例(类似axios.create)
export const createWebSocket = (options: Parameters<typeof WS.prototype.constructor>[0]) => {
return new WS(options)
}
// 默认实例
const service = createWebSocket({
url: 'ws://your-api-endpoint',
maxReconnects: 5
})
// 添加请求拦截器
service.interceptors.send.push((data) => {
// 添加认证信息
if (!data.headers) data.headers = {}
data.headers.token = localStorage.getItem('token')
return data
})
// 添加响应拦截器
service.interceptors.receive.push((data) => {
// 统一错误处理
if (data.code && data.code !== 200) {
throw new Error(data.message)
}
return data.payload
})
export default service
```
### 核心功能解析:
1. **连接管理**
- 自动重连机制:当异常断开时自动尝试重连(最多重试 $n$ 次)
- 心跳检测:通过定时发送心跳包维持连接 $$ \text{心跳间隔} = 30\text{秒} $$
2. **拦截器系统**
```typescript
// 发送拦截器示例
service.interceptors.send.push(data => {
data.timestamp = Date.now()
return data
})
// 接收拦截器示例
service.interceptors.receive.push(data => {
if (data.error) throw new Error(data.error)
return data
})
```
3. **状态管理**
- 内置连接状态跟踪(通过 WebSocket 的 `readyState`)
- 提供明确的错误分类处理:
$$ \text{错误类型} \in \{\text{网络错误}, \text{协议错误}, \text{业务错误}\} $$
4. **使用示例(Vue3组件)**
```typescript
import { onMounted, onUnmounted } from 'vue'
import ws from '@/utils/websocket'
export default {
setup() {
const handleMessage = (data) => {
console.log('处理消息:', data)
}
onMounted(async () => {
try {
await ws.connect()
ws.send({ type: 'subscribe', channel: 'updates' })
} catch (error) {
console.error('连接失败:', error)
}
})
onUnmounted(() => {
ws.close()
})
return { handleMessage }
}
}
```
### 设计要点:
1. **自动重连策略**:采用指数退避算法优化重连机制
$$ \text{重连间隔} = \min(2^{n} \times \text{基础间隔}, \text{最大间隔}) $$
2. **心跳保活**:防止 NAT 超时断开连接,间隔建议值:
$$ \text{心跳间隔} \leq \text{运营商 NAT 超时时间} \Rightarrow 通常 25-30\text{秒} $$
3. **错误隔离**:区分网络层错误与业务层错误,通过不同拦截器处理
4. **类型安全**(推荐使用 TypeScript):
```typescript
interface WSOptions {
url: string
protocols?: string | string[]
maxReconnects?: number
reconnectInterval?: number
heartbeat?: number
}
```
该封装方案实现了 WebSocket 的核心管理功能,同时保持了与 axios 相似的开发体验。开发者可以通过扩展 `handleMessage` 方法或添加拦截器来实现业务定制逻辑。
阅读全文
相关推荐


















