咱们在作聊天室的时候,会须要用到实时通讯,当服务端向客户端提早声明,发送的是流信息的时候,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…