服务器与客户端的实时通讯

服务器与客户端的实时通讯

咱们在作聊天室的时候,会须要用到实时通讯,当服务端向客户端提早声明,发送的是流信息的时候,HTTP 协议能够容许服务器向客户端发送消息,由于一次性发送不完,须要接二连三的发送,客户端不会关闭链接,会一直等着服务器发送新的数据流。javascript

服务端与客户端的实时通讯,主要有如下三种解决方案:css

轮询

前端能够在本身的页面进行轮询(定时)调用后端的接口,而后触发后端给前端返回消息,虽然能够解决先后端实时推送的数据问题,可是这样作并非一个最优解,使用 WebSocket 和 SSE 更好一点。html

WebSocket

WebSocket 是一个全双工通道,客户端能够给服务端发送消息,而且能够接收服务端的消息,服务端也能够给客户端发送消息,接收客户端的消息。前端

websocket 有不少特色:java

  1. 创建在 TCP 协议之上,服务器端的实现比较容易
  2. 与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,而且握手阶段采用 HTTP 协议,所以握手时不容易屏蔽,能经过各类 HTTP 代理服务器。
  3. 数据格式比较轻量,性能开销小,通讯高效。
  4. 能够发送文本,也能够发送二进制数据。
  5. 没有同源限制,客户端能够与任意服务器通讯。
  6. 协议标识符是 ws(若是加密,则为 wss),服务器网址就是 URL。

像直播的聊天室都是 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>
复制代码
  • 前端经过 socket.on('事件名', callback)监听到后端的触发
  • 前端经过 socket.emit('事件名', '消息体')向后端发送消息
  • 后端经过 socket.emit('事件名', '消息体')向前端发送消息
  • 后端经过 socket.on('事件名', callback)接收前端发送来的消息
  • 后端经过 socket.on('disconnect')监听退出事件
  • 后端能够经过 socket.broadcast.emit('message', '消息内容')进行广播

SSE(Server-Sent Events)

SSE 相对于 WebSocket 来讲,没有 WebSocket 那么强大,由于 WebSocket 是全双工通道,可是 SSE 是单向通道,只能服务器向浏览器发送信息。浏览器

可是 SSE 相对 WebSocket 来讲,也有本身的优势:

  1. 轻量级,使用简单,没有 WebSocket 的协议那么复杂
  2. 默认断线重连,WebSocket 须要本身去实现
  3. SSE 通常用来发送文本,若是发送二进制数据,须要编码后传输,WebSocket 默认支持传送二进制数据

具体的代码示例能够参考 javascript.ruanyifeng.com/htmlapi/eve…

相关文章
相关标签/搜索