咱們在作聊天室的時候,會須要用到實時通訊,當服務端向客戶端提早聲明,發送的是流信息的時候,HTTP 協議能夠容許服務器向客戶端發送消息,由於一次性發送不完,須要接二連三的發送,客戶端不會關閉鏈接,會一直等着服務器發送新的數據流。javascript
服務端與客戶端的實時通訊,主要有如下三種解決方案:css
前端能夠在本身的頁面進行輪詢(定時)調用後端的接口,而後觸發後端給前端返回消息,雖然能夠解決先後端實時推送的數據問題,可是這樣作並非一個最優解,使用 WebSocket 和 SSE 更好一點。html
WebSocket 是一個全雙工通道,客戶端能夠給服務端發送消息,而且能夠接收服務端的消息,服務端也能夠給客戶端發送消息,接收客戶端的消息。前端
websocket 有不少特色:java
像直播的聊天室都是 WebSocket 作的。咱們在使用 WebSocket 的時候,可使用 socket.io 這個庫,會方便不少。在前端頁面須要依靠 socket.io.js,node 要依靠socket.io的庫。node
用一個簡單的 socket.io 的例子,實現一下精簡版的互相通訊。廢話很少說,上代碼:web
server 端:後端
const Koa = require('koa');
const app = new Koa();
const server = require('http').Server(app.callback());
const io = require('socket.io')(server);
const port = 8081;
server.listen(process.env.PORT || port, () => {
console.log(`app run at : http://127.0.0.1:${port}`);
});
io.on('connection', socket => {
console.log('初始化成功!下面能夠用socket綁定事件和觸發事件了');
socket.on('send', data => {
console.log('客戶端發送的內容:', data);
socket.emit('getMsg', '我是返回的消息... ...');
});
setInterval(() => {
socket.emit('getMsg', '我是初始化3s後的返回消息... ...');
}, 3000);
});
複製代碼
client 端:api
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>websocket示例</title>
</head>
<body>
<button id="send">發送消息到服務器</button>
<div>
<h3>服務器響應的消息:</h3>
<i id="msg"></i>
</div>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
<script> var socket = io('ws://localhost:8081'); var send = document.querySelector('#send'); var msg = document.querySelector('#msg'); socket.on('getMsg', data => { console.log('服務端消息:', data); msg.innerHTML += `${data} <br/>`; }); socket.on('message', data => { console.log('服務端消息:', data); // msg.innerHTML += `${data} <br/>`; }); send.onclick = () => { console.log('點擊了發送消息!'); socket.emit('send', 'hello'); }; </script>
</body>
</html>
複製代碼
SSE 相對於 WebSocket 來講,沒有 WebSocket 那麼強大,由於 WebSocket 是全雙工通道,可是 SSE 是單向通道,只能服務器向瀏覽器發送信息。瀏覽器
可是 SSE 相對 WebSocket 來講,也有本身的優勢:
具體的代碼示例能夠參考 javascript.ruanyifeng.com/htmlapi/eve…