前端——WebSocket实时通信在项目中的应用
Vue | July 11, 2026
文章链接:https://blog.csdn.net/qq_43201350/article/details/156124656
WebSocket提供了全双工通信能力,适用于实时性要求高的应用场景。本文将介绍WebSocket在前端项目中的实践。
1 WebSocket基础使用
// WebSocket客户端封装
class WebSocketClient {
constructor(url, options = {}) {
this.url = url
this.options = {
reconnectInterval: 1000,
maxReconnectAttempts: 5,
...options
}
this.reconnectAttempts = 0
this.listeners = {}
this.connect()
}
connect() {
this.ws = new WebSocket(this.url)
this.ws.onopen = () => {
console.log('WebSocket连接已建立')
this.reconnectAttempts = 0
this.emit('open')
}
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data)
this.emit(data.type, data.payload)
}
this.ws.onclose = () => {
console.log('WebSocket连接已关闭')
this.handleReconnect()
this.emit('close')
}
this.ws.onerror = (error) => {
console.error('WebSocket错误:', error)
this.emit('error', error)
}
}
handleReconnect() {
if (this.reconnectAttempts < this.options.maxReconnectAttempts) {
this.reconnectAttempts++
setTimeout(() => {
console.log(`尝试重新连接 (${this.reconnectAttempts}/${this.options.maxReconnectAttempts})`)
this.connect()
}, this.options.reconnectInterval)
}
}
send(type, payload) {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({ type, payload }))
}
}
on(event, callback) {
if (!this.listeners[event]) {
this.listeners[event] = []
}
this.listeners[event].push(callback)
}
emit(event, data) {
if (this.listeners[event]) {
this.listeners[event].forEach(callback => callback(data))
}
}
}
2 实时消息组件
<template>
<div class="chat-container">
<div class="messages" ref="messagesContainer">
<div
v-for="message in messages"
:key="message.id"
:class="['message', message.type]"
>
<div class="message-content">{{ message.content }}</div>
<div class="message-time">{{ formatTime(message.timestamp) }}</div>
</div>
</div>
<div class="input-area">
<input
v-model="inputMessage"
@keyup.enter="sendMessage"
placeholder="输入消息..."
>
<button @click="sendMessage">发送</button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue'
import WebSocketClient from '@/utils/websocket'
const messages = ref([])
const inputMessage = ref('')
const messagesContainer = ref(null)
const wsClient = ref(null)
onMounted(() => {
wsClient.value = new WebSocketClient('ws://localhost:8080/chat')
wsClient.value.on('message', (data) => {
messages.value.push({
id: Date.now(),
type: 'received',
content: data.content,
timestamp: new Date()
})
scrollToBottom()
})
wsClient.value.on('system', (data) => {
messages.value.push({
id: Date.now(),
type: 'system',
content: data.content,
timestamp: new Date()
})
scrollToBottom()
})
})
const sendMessage = () => {
if (!inputMessage.value.trim()) return
wsClient.value.send('message', {
content: inputMessage.value
})
messages.value.push({
id: Date.now(),
type: 'sent',
content: inputMessage.value,
timestamp: new Date()
})
inputMessage.value = ''
scrollToBottom()
}
const scrollToBottom = () => {
nextTick(() => {
if (messagesContainer.value) {
messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
}
})
}
const formatTime = (timestamp) => {
return timestamp.toLocaleTimeString()
}
</script>
3 心跳检测与断线重连
// 带心跳检测的WebSocket客户端
class HeartbeatWebSocket extends WebSocketClient {
constructor(url, options = {}) {
super(url, options)
this.heartbeatInterval = options.heartbeatInterval || 30000
this.heartbeatTimer = null
}
connect() {
super.connect()
// 启动心跳检测
this.startHeartbeat()
}
startHeartbeat() {
this.heartbeatTimer = setInterval(() => {
this.send('ping', { timestamp: Date.now() })
}, this.heartbeatInterval)
}
stopHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer)
this.heartbeatTimer = null
}
}
handleReconnect() {
this.stopHeartbeat()
super.handleReconnect()
}
close() {
this.stopHeartbeat()
if (this.ws) {
this.ws.close()
}
}
}