瀏覽器和服務器之間的通信更便利,比http的輪詢等效率提高很多,
WebSocket并不是權限的協議,而是利用http協議來建立連接
websocket必須由瀏覽器發起請求,協議是一個標準的http請求,格式如下
GET ws://example.com:3000/chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.com:3000
關鍵字段解釋:?
?Upgrade: websocket?:表示客戶端希望升級到 WebSocket 協議。
?Connection: Upgrade?:確認協議升級。
?Sec-WebSocket-Key?:一個 Base64 編碼的隨機值(16字節),用于握手驗證。
?Sec-WebSocket-Version?:指定 WebSocket 協議版本(通常為 13)。
?Origin?(可選):用于跨域控制,服務器可據此決定是否允許連接。
服務器響應(Server Handshake Response)?
服務器返回 ?HTTP 101 Switching Protocols? 狀態碼,確認協議升級:
Copy Code
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
?關鍵字段解釋:?
?Sec-WebSocket-Accept?:服務器將客戶端的 Sec-WebSocket-Key 與固定 GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接后,進行 SHA-1 哈希并 Base64 編碼,返回此值供客戶端驗證。
握手成功后,通信將脫離 HTTP,轉為基于幀的 WebSocket 協議。
為什么websocket連接可以實現雙工通信,而http不可以呢?實際上上,http是建立在tcp之上的,tcp本身就實現了雙工通信,但http協議的請求--應答機制限制了全雙工通信。websocket連接建立以后,其實只是簡單規定了一下:咱們接下來的通信就不使用http了,咱們直接互發數據吧。
安全的websocket連接機制和https類似,首先,瀏覽器用wss://創建websocket連接,會先通過https創建安全連接,然后,該https升級為websocket連接,底層通信仍然走的是安全的SSL/TLS
uniapp使用websocket,需實現心跳?:防止因網絡空閑導致連接斷開
let timer;
const socketTask = uni.connectSocket({ url: 'wss://example.com' });socketTask.onOpen(() => {timer = setInterval(() => {socketTask.send({ data: 'ping' });}, 30000);
});socketTask.onClose(() => {clearInterval(timer);
});
?Node.js 服務端設置 WebSocket 跨域:(關鍵在于 ?握手階段對 Origin 頭的驗證)
const WebSocket = require('ws');// 允許的 Origin 白名單
const allowedOrigins = ['https://your-frontend-domain.com','http://localhost:3000'
];const wss = new WebSocket.Server({port: 8080,verifyClient: (info) => {const origin = info.origin || info.req.headers.origin;if (!allowedOrigins.includes(origin)) {console.log(`拒絕來自 ${origin} 的跨域請求`);return false; // 阻止握手}return true; // 允許連接}
});wss.on('connection', (ws) => {console.log('客戶端已連接');
});