使用 WebSocket 实现实时通信的 Vue 应用
前言
在现代 Web 应用中,实时通信是提升用户体验的重要因素之一。WebSocket 协议提供了一种在客户端和服务器之间建立持久连接的方式,使得双向数据传输成为可能。本文将通过两个代码段,展示如何在 Vue 应用中使用 WebSocket 实现实时消息接收和发送。
1. WebSocketService 类
首先,我们定义一个
WebSocketService
类,用于管理 WebSocket 连接及其相关操作。以下是该类的实现:
1.1 类属性
- socket: WebSocket | null: 存储 WebSocket 实例,用于与服务器进行实时通信。初始值为 null,在调用 connect() 方法时创建 WebSocket 实例。
- count: number: 计数器,用于统计接收到的 WebSocket 消息的数量。每次接收到新消息时,计数器会自增。
- token: string: 从用户状态中提取的令牌(token),用于认证。通过 useUserStore() 获取用户的 token 并保存下来,用于 WebSocket 的连接和认证。
- isConnected: boolean: 表示 WebSocket 是否成功连接到服务器。初始值为 false,在 onOpen() 方法中连接成功后设置为 true。
- onMessageCallback: ((message: any) => void) | null: 用于存储一个回调函数,当 WebSocket 接收到消息时会调用此回调函数并传递消息内容。初始值为 null,通过 onMessageReceived() 方法注册。
private socket: WebSocket |null=null;// 存储 WebSocket 实例private count:number=0;// 统计接收到的消息数量private token:string;// 用于存储从用户状态中获取的令牌 (token)private isConnected:boolean=false;// 用于判断是否连接成功private onMessageCallback:((message:any)=>void)|null=null;// 消息回调函数
1.2 构造函数和连接初始化
- 构造函数接受一个 socketUrl 参数,用于指定 WebSocket 服务器的地址。
- 使用 useUserStore() 从用户状态中获取 token,存储在 this.token 中。
- 调用 connect(socketUrl) 方法与服务器建立 WebSocket 连接。
constructor(socketUrl:string){const userStore =useUserStore();this.token = userStore.token;this.connect(socketUrl);}
1.3 WebSocket 连接
connect(socketUrl) 方法创建一个新的 WebSocket 实例,传入 socketUrl 和 this.token 作为子协议,用于与服务器通信。
为 WebSocket 注册了以下事件监听器:
- open: 当连接成功时触发,调用 onOpen() 方法。
- message: 当接收到服务器消息时触发,调用 onMessage() 方法。
- error: 当发生错误时触发,调用 onError() 方法。
- close: 当连接关闭时触发,调用 onClose() 方法。
privateconnect(socketUrl:string){this.socket =newWebSocket(socketUrl,this.token);this.socket.addEventListener('open',(event)=>{this.onOpen(event);});this.socket.addEventListener('message',(event)=>{this.onMessage(event);});this.socket.addEventListener('error',(event)=>{this.onError(event);});this.socket.addEventListener('close',(event)=>{this.onClose(event);});}
1.4 事件处理方法
onOpen(event: Event): 在 WebSocket 连接成功后触发。
- 发送认证信息(Authorization: Bearer token)给服务器,用于身份验证。
- 将 isConnected 设置为 true,表示连接成功。
- 打印 “WebSocket connection established” 到控制台。
privateonOpen(event: Event){if(this.socket){this.socket.send('Authorization: Bearer '+this.token);this.isConnected =true;console.log("WebSocket connection established");}}
onMessage(event: MessageEvent): 当 WebSocket 接收到消息时触发。
- 增加消息计数器 count。
- 如果注册了 onMessageCallback,则调用回调函数并传递消息数据。
privateonMessage(event: MessageEvent){this.count++;console.log('Received:',this.count);const messageData = event.data;if(this.onMessageCallback){this.onMessageCallback(messageData);}}
onError(event: Event): 当 WebSocket 出现错误时触发。
- 打印错误信息到控制台,帮助调试。
privateonError(event: Event){console.error("WebSocket error observed:", event);}
onClose(event: CloseEvent): 当 WebSocket 连接关闭时触发。
- 将 isConnected 设置为 false,表示连接已断开。
- 打印连接关闭信息到控制台。
privateonClose(event: CloseEvent){console.log("WebSocket closed:", event);this.isConnected =false;}
1.5 发送和关闭 WebSocket 消息
sendMessage(message: string): 用于发送消息到服务器。
- 如果 WebSocket 连接状态为 OPEN,则发送消息。
- 否则打印错误信息并显示 WebSocket 当前的 readyState。
publicsendMessage(message:string){if(this.socket &&this.socket.readyState === WebSocket.OPEN){this.socket.send(message);}else{console.error("WebSocket is not open. ReadyState:",this.socket?.readyState);}}
close(): 手动关闭 WebSocket 连接。
publicclose(){if(this.socket){this.socket.close();}}
1.6 状态查询与回调注册
isConnectedSuccessfully(): 用于查询 WebSocket 当前的连接状态,返回 true 或 false。
publicisConnectedSuccessfully():boolean{returnthis.isConnected;}
onMessageReceived(callback: (message: any) => void): 注册一个消息处理回调函数,当 WebSocket 接收到消息时触发该回调函数。
publiconMessageReceived(callback:(message:any)=>void){this.onMessageCallback = callback;}
1.7 完整代码
import{ useUserStore }from"../module/user";classWebSocketService{private socket: WebSocket |null=null;// 存储 WebSocket 实例private count:number=0;// 统计接收到的消息数量private token:string;// 用于存储从用户状态中获取的令牌 (token)private isConnected:boolean=false;// 用于判断是否连接成功private onMessageCallback:((message:any)=>void)|null=null;// 消息回调函数constructor(socketUrl:string){const userStore =useUserStore();this.token = userStore.token;this.connect(socketUrl);}privateconnect(socketUrl:string){this.socket =newWebSocket(socketUrl,this.token);this.socket.addEventListener('open',(event)=>{this.onOpen(event);});this.socket.addEventListener('message',(event)=>{this.onMessage(event);});this.socket.addEventListener('error',(event)=>{this.onError(event);});this.socket.addEventListener('close',(event)=>{this.onClose(event);});}privateonOpen(event: Event){if(this.socket){this.socket.send('Authorization: Bearer '+this.token);this.isConnected =true;// 连接成功console.log("WebSocket connection established");}}privateonMessage(event: MessageEvent){this.count++;console.log('Received:',this.count);const messageData = event.data;// 获取消息内容if(this.onMessageCallback){this.onMessageCallback(messageData);// 调用回调函数,传递消息内容}}privateonError(event: Event){console.error("WebSocket error observed:", event);}privateonClose(event: CloseEvent){console.log("WebSocket closed:", event);this.isConnected =false;// 连接关闭}publicsendMessage(message:string){if(this.socket &&this.socket.readyState === WebSocket.OPEN){this.socket.send(message);}else{console.error("WebSocket is not open. ReadyState:",this.socket?.readyState);}}publicclose(){if(this.socket){this.socket.close();}}publicisConnectedSuccessfully():boolean{returnthis.isConnected;}publiconMessageReceived(callback:(message:any)=>void){this.onMessageCallback = callback;}}exportdefault WebSocketService;
2. 在 Vue 组件中使用 WebSocketService
在 Vue 组件中,我们可以利用
onMounted
和
onBeforeUnmount
生命周期钩子来管理 WebSocket 的生命周期。以下是如何在 Vue 组件中使用
WebSocketService
的示例代码:
import{ onMounted, onBeforeUnmount }from'vue';import WebSocketService from'../../store/module/websocket';const socketUrl ='http://123.123.123.123:端口号/ws';const websocketService =newWebSocketService(socketUrl);onMounted(()=>{// 接收消息
websocketService.onMessageReceived((message)=>{
console.log("New message received:", message);// 在这里处理接收到的消息});});// 关闭 WebSocket 连接onBeforeUnmount(()=>{
websocketService.close();
console.log("WebSocket connection closed.");});
2.1 定义 WebSocket URL
const socketUrl = http://123.123.123.123:8088/ws’; 这一行定义了一个字符串 socketUrl,它表示要连接的 WebSocket 服务器的 URL。这个 URL 指向一个运行在 IP 地址为 123.123.123.123 的服务器上,端口为 8088,并且使用 /ws 路径。
2.2 实例化 WebSocketService
const websocketService = new WebSocketService(socketUrl); 这一行创建了 WebSocketService 类的一个实例,并将之前定义的 socketUrl 作为参数传递给构造函数。
2.3 生命周期钩子
- onMounted: 当组件挂载时,注册接收消息的回调函数。这允许我们在接收到新消息时进行相应处理。
- onBeforeUnmount: 当组件卸载时,调用
close
方法关闭 WebSocket 连接,以释放资源。
3. 总结
通过上述代码,我们实现了一个简单的 WebSocket 服务,能够在 Vue 应用中进行实时通信。WebSocket 的全双工通信特性使得我们能够高效地处理实时数据,而封装好的
WebSocketService
类则使得代码更加模块化和易于维护。
无论是聊天应用、实时通知还是在线游戏,WebSocket 都是实现实时交互的重要工具。希望本文能帮助你更好地理解和使用 WebSocket。在实际开发中,可以根据具体需求扩展和优化这个基础实现。
版权归原作者 土豆马铃薯_777 所有, 如有侵权,请联系我们删除。