JavaScript - Polling、WebSocket 与 SSE 介绍

小弟最近因缘际会下接触了聊天室,后来查阅了一下目前有 Polling、WebSocket 与 SSE 三种实作方法,这边比较一下各个方法的差异与特性

Polling

Polling 中文翻译为轮询,你可能没听过,但是你一定用过,其实说白了就是不断的去呼叫 function 而已,其中又分为 PollingLong Polling,以下做介绍

Polling(轮询)

Polling 每隔固定的时间就呼叫一次 function

function shortPolling() {  console.log("Short Polling");}setInterval(shortPolling, 1000);

Long Polling(长轮询)

Long Polling 则是在 function 返回后再次呼叫该 function

function longPolling() {  setTimeout(function() {    console.log("Long Polling");    longPolling();  }, 1000);}longPolling();

分析

优点:实现容易、支援度高缺点:非常耗资源、无法即时响应

WebSocket

WebSocket 是一种网路传输协定,在 WebSocket API 中,Client 与 Server 只需要完成一次交握,两者之间就可以建立永续性的连接,它让资料能够更有效率的做交换,后端这边使用 ws 做Demo

Demo(后端)

// 载入  wsconst WebSocket = require("ws");// 设定 WebSocketconst wss = new WebSocket.Server({ port: 3000 });// WebSocket APIwss.on("connection", function connection(ws) {  // 接收 Client 端讯息  ws.on("message", function incoming(message) {    console.log(message);  });  // 传送 Server 端讯息  ws.send("我是 Server");});

Demo(前端)

// WebSocket APIconst ws = new WebSocket("ws://localhost:3000");// 连接 API 并传送 Client 端讯息ws.onopen = function() {  ws.send("我是 Client");};// 接收 Server 端讯息ws.onmessage = function(e) {  console.log(e.data);};

分析

优点:节省资源、优异的即时性缺点:伺服器维护成本较高、支援度较其他低

踩雷小补充

如果前端需要订阅某个 Channel 写法如下

const ws = new WebSocket("ws://localhost:3000");ws.onopen = function() {  // 增加以下两行,ChannelName 改为订阅的频道名称  const subscribe = { command: 'subscribe', identifier: '{"channel":"ChannelName"}' }  ws.send(JSON.stringify(subscribe))};ws.onmessage = function(e) {  console.log(e.data);};

SSE(Server-Sent Events)

SSE 是 HTML5 标準的 API,他在 Client 连接至 Server 后,透过一般的 http 协定主动将资料推送至 Client,并且不会断开连接,使用时须要按照规定的格式,先我们先认识一下写法

资料格式

前方加上 data:,资料结尾须加上 \n\n,若只有 \n 为换行

// 单行data: message\n\n// 多行data: first message\ndata: second message\n\n

重新连线时间

当连线意外中断后,如果有设定 retry: 时间,则时间一到会重新连线

// 中断连线后5秒重新连结retry: 5000\n

自订事件名称

指定事件名称时可使用 event: 来做,预设为 message

event: myEvent\n

Demo(后端)

这边 Demo 使用 express 与 cors

// 载入 express 与 corsconst express = require("express");const cors = require("cors");const app = express();// 使用 cors 套件app.use(cors());// 设定 SSE APIapp.get("/", function(req, res) {  // 设定 SSE header  res.header({    "Content-Type": "text/event-stream",    "Cache-Control": "no-cache",    Connection: "keep-alive"  });  // 设定重新连接时间  res.write("retry: 1000\n");    let data = {    name: "ares",    time: null  };  // 每隔3秒传送一次资料  setInterval(() => {    defaultEvent();    myEvent();  }, 3000);  // 预设事件 - message  function defaultEvent() {    data.time = new Date();    res.write(`data: ${JSON.stringify(data)}\n\n`);  }  // 自订事件 - myEvent  function myEvent() {    data.time = new Date();    res.write("event: myEvent\n");    res.write(`data: ${JSON.stringify(data)}\n\n`);  }});// 监听 3000 portapp.listen(3000);

Demo(前端)

// SSE APIconst sse = new EventSource("http://localhost:3000");// 连接时触发此事件sse.addEventListener("open", e => console.log("开启连接"));// 连线中断或其他错误触发此事件sse.addEventListener("error", e => console.log("关闭连接"));// 预设事件 - messagesse.addEventListener("message", e =>  console.log("message:", JSON.parse(e.data)));// 自订事件 - myEventsse.addEventListener("myEvent", e =>  console.log("myEvent:", JSON.parse(e.data)));// 设定十秒后关闭连接setTimeout(() => {  sse.close();}, 10000);

分析

优点:节省资源、支援度高缺点:无法即时响应

结语

看过这些方法后发现,WebSocket 适合拿来做线上游戏、聊天室,只是支援度较其他低,而 Polling 适合功能简单资源度低的地方,SSE 基本上就是 Polling 的升级版,适合拿来做新闻页面、即时股价的应用,各有各的使用情境~


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章