前端實時通信技術大抵可分為Eventsource、websocket與socket.io這三種,以下總結這三者的差異和優缺點
EventSource
EventSource 是一種輕量級的 API,用于擷取來自伺服器的實時事件。它是 WebSockets 的替代方案,因為它比 WebSockets 更簡單,更适合處理伺服器向用戶端發送資料的情況。使用 EventSource,隻有伺服器能夠發送消息,是以它更安全。但是,它不支援雙向通信或用戶端發送消息。
優點:
- 簡單易用,與 HTTP 協定相容。
- 隻需要一個長連接配接,伺服器可以推送任意數量的事件。
- 适用于服務端向用戶端發送頻率較低的資料。
- 可以自動重連,并且在連接配接斷開時會觸發 error 和 close 事件,友善處理異常情況。
缺點:
- 不支援雙向通信。
- 不支援二進制資料傳輸。
- 相容性存在問題,不支援 IE 浏覽器。
示例:
const eventSource = new EventSource('/api/data');
eventSource.addEventListener('message', (event) => {
console.log('Received message data:', event.data);
});
eventSource.addEventListener('error', (event) => {
if (event.eventPhase === EventSource.CLOSED) {
console.log('Connection was closed.');
} else {
console.error('An error occurred:', event);
}
});
WebSocket
WebSocket 是一種在單個 TCP 連接配接上提供全雙工通信的協定,它使得用戶端和伺服器之間進行實時互動變得更加容易。它是一種标準化的通信協定,用戶端和伺服器都可以通過它發送消息。
優點:
- 支援雙向通信,用戶端和服務端都可以發送和接收消息;
- 可以發送二進制資料,支援大檔案傳輸;
- 協定比較輕量級,能夠節省網絡帶寬和伺服器資源;
- 相容性較好,大部分現代浏覽器都支援 WebSocket。
缺點:
- 需要在服務端實作 WebSocket 協定的支援;
- 相對于 HTTP 請求來說,WebSocket 連接配接需要占用更多的服務端資源;
- 安全性問題:需要注意防止 CSRF 和 XSS 攻擊,避免惡意使用者利用 WebSocket 劫持會話或注入腳本等。
示例:
const webSocket = new WebSocket('ws://localhost:8080');
webSocket.addEventListener('open', (event) => {
console.log('WebSocket connection established!');
});
webSocket.addEventListener('message', (event) => {
console.log('Received message data:', event.data);
});
webSocket.addEventListener('close', (event) => {
console.log('WebSocket connection closed!');
});
webSocket.addEventListener('error', (event) => {
console.error('An error occurred:', event);
});
// 發送消息到伺服器
webSocket.send('Hello, server!');
Socket.IO
Socket.IO 是一個庫,它封裝了 WebSocket 和其他實時通信協定,并提供了一組易于使用的 API。它既可以在用戶端上使用,也可以在伺服器端上使用,它還提供了許多進階功能,例如自動重連、心跳機制和房間等概念。
優點:
- 支援雙向通信。
- 支援廣播和房間功能,使得開發者可以輕松地實作實時應用程式。
- 自帶多種傳輸方式,如 WebSocket、HTTP 長輪詢、JSONP 等,可以根據浏覽器或裝置的不同選擇最佳傳輸方式。
缺點:
- 使用 Socket.IO 的應用程式需要使用 Socket.IO 作為通信層,不能在應用程式中內建原生 WebSocket 或 EventSource。
- 對比 EventSource 和 WebSocket,Socket.IO 相對來說更加龐大,需要引入相應的用戶端庫和伺服器端插件,如果應用程式隻需要簡單的實時通信,使用 EventSource 或 WebSocket 可能更加适合
示例:
// 用戶端代碼
const socket = io('http://localhost:3000');
socket.on('connect', () => {
console.log('Socket.io connection established!');
});
socket.on('message', (data) => {
console.log('Received message data:', data);
});
socket.on('disconnect', () => {
console.log('Socket.io connection closed!');
});
socket.emit('message', 'Hello, server!');
// 服務端代碼
const io = require('socket.io')(3000);
io.on('connection', (socket) => {
console.log('A new client is connected!');
socket.on('message', (data) => {
console.log('Received message data:', data);
socket.emit('message', `You said: ${data}`);
});
socket.on('disconnect', () => {
console.log('Client disconnected!');
});
});
版權聲明:本文為CSDN部落客「我胖虎不答應!!」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。原文連結:https://blog.csdn.net/weixin_42508580/article/details/130931268