企業(yè)網(wǎng)站 帶后臺聊城seo整站優(yōu)化報價
使用 WebSocket 實現(xiàn)實時通信的 Vue 應(yīng)用
- 前言
- 1. WebSocketService 類
-
- 1.1 類屬性
- 1.2 構(gòu)造函數(shù)和連接初始化
- 1.3 WebSocket 連接
- 1.4 事件處理方法
- 1.5 發(fā)送和關(guān)閉 WebSocket 消息
- 1.6 狀態(tài)查詢與回調(diào)注冊
- 1.7 完整代碼
- 2. 在 Vue 組件中使用 WebSocketService
-
- 2.1 定義 WebSocket URL
- 2.2 實例化 WebSocketService
- 2.3 生命周期鉤子
- 3. 總結(jié)
前言
在現(xiàn)代 Web 應(yīng)用中,實時通信是提升用戶體驗的重要因素之一。WebSocket 協(xié)議提供了一種在客戶端和服務(wù)器之間建立持久連接的方式,使得雙向數(shù)據(jù)傳輸成為可能。本文將通過兩個代碼段,展示如何在 Vue 應(yīng)用中使用 WebSocket 實現(xiàn)實時消息接收和發(fā)送。
1. WebSocketService 類
首先,我們定義一個 WebSocketService
類,用于管理 WebSocket 連接及其相關(guān)操作。以下是該類的實現(xiàn):
1.1 類屬性
-
socket: WebSocket | null: 存儲 WebSocket 實例,用于與服務(wù)器進行實時通信。初始值為 null,在調(diào)用 connect() 方法時創(chuàng)建 WebSocket 實例。
-
count: number: 計數(shù)器,用于統(tǒng)計接收到的 WebSocket 消息的數(shù)量。每次接收到新消息時,計數(shù)器會自增。
-
token: string: 從用戶狀態(tài)中提取的令牌(token),用于認證。通過 useUserStore() 獲取用戶的 token 并保存下來,用于 WebSocket 的連接和認證。
-
isConnected: boolean: 表示 WebSocket 是否成功連接到服務(wù)器。初始值為 false,在 onOpen() 方法中連接成功后設(shè)置為 true。
-
onMessageCallback: ((message: any) => void) | null: 用于存儲一個回調(diào)函數(shù),當 WebSocket 接收到消息時會調(diào)用此回調(diào)函數(shù)并傳遞消息內(nèi)容。初始值為 null,通過 onMessageReceived() 方法注冊。
private socket: WebSocket | null = null; // 存儲 WebSocket 實例
private count: number = 0; // 統(tǒng)計接收到的消息數(shù)量
private token: string; // 用于存儲從用戶狀態(tài)中獲取的令牌 (token)
private isConnected: boolean = false; // 用于判斷是否連接成功
private onMessageCallback: ((message: any) => void) | null = null; // 消息回調(diào)函數(shù)
1.2 構(gòu)造函數(shù)和連接初始化
-
構(gòu)造函數(shù)接受一個 socketUrl 參數(shù),用于指定 WebSocket 服務(wù)器的地址。
-
使用 useUserStore() 從用戶狀態(tài)中獲取 token,存儲在 this.token 中。
-
調(diào)用 connect(socketUrl) 方法與服務(wù)器建立 WebSocket 連接。
constructor(socketUrl: string) {
const userStore = useUserStore();
this.token = userStore.token;
this.connect(socketUrl);
}
1.3 WebSocket 連接
connect(socketUrl) 方法創(chuàng)建一個新的 WebSocket 實例,傳入 socketUrl 和 this.token 作為子協(xié)議,用于與服務(wù)器通信。
為 WebSocket 注冊了以下事件監(jiān)聽器:
-
open: 當連接成功時觸發(fā),調(diào)用 onOpen() 方法。
-
message: 當接收到服務(wù)器消息時觸發(fā),調(diào)用 onMessage() 方法。
-
error: 當發(fā)生錯誤時觸發(fā),調(diào)用 onError() 方法。
-
close: 當連接關(guān)閉時觸發(fā),調(diào)用 onClose() 方法。
private connect(socketUrl: string) {
this.socket = new WebSocket(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 連接成功后觸發(fā)。
-
發(fā)送認證信息(Authorization: Bearer token)給服務(wù)器,用于身份驗證。
-
將 isConnected 設(shè)置為 true,表示連接成功。
-
打印 “WebSocket connection established” 到控制臺。
private onOpen(event: Event) {
if (this.socket) {
this.socket.send('Authorization: Bearer ’ + this.token);
this.isConnected = true;
console.log(“WebSocket connection established”);
}
}
onMessage(event: MessageEvent): 當 WebSocket 接收到消息時觸發(fā)。
-
增加消息計數(shù)器 count。
-
如果注冊了 onMessageCallback,則調(diào)用回調(diào)函數(shù)并傳遞消息數(shù)據(jù)。
private onMessage(event: MessageEvent) {
this.count++;
console.log(‘Received:’, this.count);const messageData = event.data;if (this.onMessageCallback) {this.onMessageCallback(messageData); }
}
onError(event: Event): 當 WebSocket 出現(xiàn)錯誤時觸發(fā)。
-
打印錯誤信息到控制臺,幫助調(diào)試。
private onError(event: Event) {
console.error(“WebSocket error observed:”, event);
}
onClose(event: CloseEvent): 當 WebSocket 連接關(guān)閉時觸發(fā)。
-
將 isConnected 設(shè)置為 false,表示連接已斷開。
-
打印連接關(guān)閉信息到控制臺。
private onClose(event: CloseEvent) {
console.log(“WebSocket closed:”, event);
this.isConnected = false;
}
1.5 發(fā)送和關(guān)閉 WebSocket 消息
sendMessage(message: string): 用于發(fā)送消息到服務(wù)器。
-
如果 WebSocket 連接狀態(tài)為 OPEN,則發(fā)送消息。
-
否則打印錯誤信息并顯示 WebSocket 當前的 readyState。
public sendMessage(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(): 手動關(guān)閉 WebSocket 連接。
public close() {if (this.socket) {this.socket.close();}
}
1.6 狀態(tài)查詢與回調(diào)注冊
isConnectedSuccessfully(): 用于查詢 WebSocket 當前的連接狀態(tài),返回 true 或 false。
public isConnectedSuccessfully(): boolean {return this.isConnected;
}
onMessageReceived(callback: (message: any) => void): 注冊一個消息處理回調(diào)函數(shù),當 WebSocket 接收到消息時觸發(fā)該回調(diào)函數(shù)。
public onMessageReceived(callback: (message: any) => void) {this.onMessageCallback = callback;
}
1.7 完整代碼
import { useUserStore } from "../module/user";class WebSocketService {private socket: WebSocket | null = null; // 存儲 WebSocket 實例private count: number = 0; // 統(tǒng)計接收到的消息數(shù)量private token: string; // 用于存儲從用戶狀態(tài)中獲取的令牌 (token)private isConnected: boolean = false; // 用于判斷是否連接成功private onMessageCallback: ((message: any) => void) | null = null; // 消息回調(diào)函數(shù)constructor(socketUrl: string) {const userStore = useUserStore();this.token = userStore.token;this.connect(socketUrl);}private connect(socketUrl: string) {this.socket = new WebSocket(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);});}private onOpen(event: Event) {if (this.socket) {this.socket.send('Authorization: Bearer ' + this.token);this.isConnected = true; // 連接成功console.log("WebSocket connection established");}}private onMessage(event: MessageEvent) {this.count++;console.log('Received:', this.count);const messageData = event.data; // 獲取消息內(nèi)容if (this.onMessageCallback) {this.onMessageCallback(messageData); // 調(diào)用回調(diào)函數(shù),傳遞消息內(nèi)容}}private onError(event: Event) {console.error("WebSocket error observed:", event);}private onClose(event: CloseEvent) {console.log("WebSocket closed:", event);this.isConnected = false; // 連接關(guān)閉}public sendMessage(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);}}public close() {if (this.socket) {this.socket.close();}}public isConnectedSuccessfully(): boolean {return this.isConnected;}public onMessageReceived(callback: (message: any) => void) {this.onMessageCallback = callback;}
}export default 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 = new WebSocketService(socketUrl);onMounted(() => {// 接收消息websocketService.onMessageReceived((message) => {console.log("New message received:", message);// 在這里處理接收到的消息});
});// 關(guān)閉 WebSocket 連接
onBeforeUnmount(() => {websocketService.close();console.log("WebSocket connection closed.");
});
2.1 定義 WebSocket URL
const socketUrl = http://123.123.123.123:8088/ws’; 這一行定義了一個字符串 socketUrl,它表示要連接的 WebSocket 服務(wù)器的 URL。這個 URL 指向一個運行在 IP 地址為 123.123.123.123 的服務(wù)器上,端口為 8088,并且使用 /ws 路徑。
2.2 實例化 WebSocketService
const websocketService = new WebSocketService(socketUrl); 這一行創(chuàng)建了 WebSocketService 類的一個實例,并將之前定義的 socketUrl 作為參數(shù)傳遞給構(gòu)造函數(shù)。
2.3 生命周期鉤子
- onMounted: 當組件掛載時,注冊接收消息的回調(diào)函數(shù)。這允許我們在接收到新消息時進行相應(yīng)處理。
- onBeforeUnmount: 當組件卸載時,調(diào)用
close
方法關(guān)閉 WebSocket 連接,以釋放資源。
3. 總結(jié)
通過上述代碼,我們實現(xiàn)了一個簡單的 WebSocket 服務(wù),能夠在 Vue 應(yīng)用中進行實時通信。WebSocket 的全雙工通信特性使得我們能夠高效地處理實時數(shù)據(jù),而封裝好的 WebSocketService
類則使得代碼更加模塊化和易于維護。
無論是聊天應(yīng)用、實時通知還是在線游戲,WebSocket 都是實現(xiàn)實時交互的重要工具。希望本文能幫助你更好地理解和使用 WebSocket。在實際開發(fā)中,可以根據(jù)具體需求擴展和優(yōu)化這個基礎(chǔ)實現(xiàn)。