今天逛牛客,看到有大佬分享說前端面試的時候遇到了關于webSocket的問題,一看自己都沒見過這個知識點,趕緊學習一下,在此記錄!
WebSocket 是一種網絡通信協議,提供了全雙工通信渠道,即客戶端和服務器可以同時發送和接收數據。這與傳統的HTTP請求不同,后者是單向的,客戶端發起請求,服務器響應請求。WebSocket 允許服務器主動向客戶端發送消息,這使得實時通信成為可能,例如在線聊天應用、實時游戲、股票行情更新等場景。
WebSocket 的基本概念
- 連接建立:客戶端通過發送一個HTTP請求來發起WebSocket連接,這個請求中包含特定的頭部,表明這是一個WebSocket握手請求。
- 握手:服務器接收到請求后,如果支持WebSocket,則響應一個HTTP響應,完成握手過程,建立WebSocket連接。
- 數據傳輸:一旦連接建立,客戶端和服務器就可以通過這個連接發送數據。數據可以是文本或二進制格式。
- 連接關閉:任何一方都可以關閉WebSocket連接。
WebSocket 的使用步驟
-
創建WebSocket實例:在客戶端,首先需要創建一個WebSocket實例,指定服務器的URL。
const ws = new WebSocket('ws://example.com/socket');
-
處理連接事件:當WebSocket連接建立時,會觸發
open
事件。ws.onopen = function(event) {console.log('WebSocket connection opened:', event); };
-
發送數據:使用
send
方法向服務器發送數據。ws.send('Hello Server!');
-
接收數據:服務器發送的數據可以通過
message
事件接收。ws.onmessage = function(event) {console.log('Message from server:', event.data); };
-
處理錯誤和關閉連接:WebSocket連接可能會遇到錯誤,或者需要主動關閉。
ws.onerror = function(error) {console.error('WebSocket Error:', error); };ws.onclose = function(event) {console.log('WebSocket connection closed:', event); };// 可以主動關閉連接 ws.close();
使用nodejs實現一個簡單的在線聊天demo。
客戶端代碼
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 簡單的HTML界面 -->
<textarea id="messageInput" placeholder="Type a message..."></textarea>
<button id="sendButton">Send</button>
<div id="messages"></div><script>// 綁定按鈕點擊事件document.getElementById('sendButton').addEventListener('click', sendMessage);// 創建WebSocket連接const ws = new WebSocket('ws://localhost:8080');const messageInput = document.getElementById('messageInput');const messagesDiv = document.getElementById('messages');const sendButton = document.getElementById('sendButton');// 連接打開時觸發ws.onopen = function(event) {console.log('Connected to the server');// 可以在這里禁用或啟用按鈕等sendButton.disabled = false;};// 接收到消息時觸發ws.onmessage = function(event) {// 將接收到的消息添加到消息顯示區域const messageElement = document.createElement('div');messageElement.textContent = event.data;messagesDiv.appendChild(messageElement);// 滾動到消息區域底部messagesDiv.scrollTop = messagesDiv.scrollHeight;};// 發送消息的函數function sendMessage() {if (ws.readyState === WebSocket.OPEN) {const message = messageInput.value;if (message) { // 確保消息不為空ws.send(message);messageInput.value = ''; // 清空輸入框}} else {console.error('WebSocket is not connected. Cannot send message.');}}// 客戶端連接錯誤時觸發ws.onerror = function(error) {console.error('WebSocket error observed:', error);// 可以在這里顯示錯誤信息或禁用發送按鈕sendButton.disabled = true;};// 客戶端關閉連接時觸發ws.onclose = function(event) {console.log('WebSocket connection closed:', event);// 可以在這里禁用發送按鈕或顯示斷開連接的信息sendButton.disabled = true;};
</script>
</body>
</html>
服務端代碼
(注意要先使用npm install ws命令安裝需要的庫)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });// 存儲所有客戶端的集合
const clients = new Set();wss.on('connection', function connection(ws) {console.log('Client connected');// 將新的客戶端WebSocket對象添加到集合中clients.add(ws);ws.on('message', function incoming(message) {console.log('received: %s', message);});ws.on('close', function() {console.log('Client disconnected');// 從集合中移除客戶端clients.delete(ws);});// 可以在這里發送歡迎消息給新連接的客戶端ws.send('Welcome to the chat!');
});// 假設我們有一個函數,用來向所有客戶端廣播消息
function broadcastMessage(message) {clients.forEach(client => {if (client.readyState === WebSocket.OPEN) {client.send(message);}});
}// 示例:每隔5秒向所有客戶端發送當前時間
setInterval(() => {const currentTime = new Date().toLocaleTimeString();broadcastMessage(`Current time: ${currentTime}`);
}, 5000);
實現效果
客戶端向服務端發送消息:
服務端向客戶端發送消息:
每隔五秒發送當前的時間