十分钟掌握前端获取实时数据的三种主流方式

news2024/11/20 20:39:51

前端获取实时数据的三种主流方式

本文聊聊前端获取实时数据的三种主要方式。想象一下,我们在网上购物时,经常能看到最新的优惠信息弹出,或者在社交媒体上看到朋友的最新动态更新。这些都是因为后端在默默地向我们的页面推送了最新的消息。那么,这背后到底使用了什么样的技术呢?主要有三种方式:轮询(Polling)、网页套接字(WebSocket) 和服务器发送事件(Server-Sent Events, SSE)。下面,我们就来近距离接触一下它们。

轮询(Polling)

原理

轮询的工作方式很像是孩子不断地问父母“我们到了吗?”。在这个比喻中,前端(孩子)定时向后端(父母)发送请求来检查是否有新数据(是否到目的地了)。轮询又分为短轮询和长轮询两种。

  • 短轮询:前端每隔一定时间就发送一个请求,无论数据是否更新,后端都立即返回响应。
  • 长轮询:前端发出请求后,后端会挂起这个请求,直到有数据更新或者超时,才返回响应。

优缺点

总体上说,轮询的优点在于它简单易实现,几乎所有的服务器和客户端技术都能支持。但缺点也很明显,因为它需要不断地发送请求,这会导致大量的网络流量,而且实时性不高,数据更新有延迟。

具体到短轮询和长轮询,可以对它俩再做一个对比:

  • 短轮询
    优点: 实现简单,兼容性好。

缺点: 频繁的请求会增加服务器负担,实时性不够,资源浪费较多。

  • 长轮询
    优点: 相比短轮询,减少了请求次数,提高了实时性。

缺点: 实现相对复杂,服务器端需要维护挂起的请求,可能会导致资源占用。

适用场景

轮询通常用在对实时性要求不是特别高的场景,比如一些后台管理系统的消息通知、网页上的非实时统计信息展示。下面是使用轮询的一些真实案例:

  • 微信扫码登录:微信的扫码登录功能使用的是轮询机制。当你扫描二维码时,你的手机上的微信客户端会向服务器发送信息,然后你的网页客户端会周期性地询问服务器,用户是否已经通过手机确认。这里使用轮询是因为登录操作并不频繁,且对实时性的要求不需要毫秒级,而且轮询是一种简单且兼容性好的实现方式。
  • Facebook的实时通知:在Facebook早期,他们使用长轮询来实现实时通知。用户的浏览器会开启一个到服务器的长连接,这样一旦有新通知,服务器就能立即推送数据。这种方式对于当时的技术来说是一个很好的折中方案,因为它在不牺牲太多实时性的情况下,减少了请求次数。

代码示例

这里演示一个短轮询。下面我们将要使用Node.js编写一段后端程序,在这段代码中我们提供两个接口,一个接口用于接受轮询、返回最新的消息,另一个接口则用于更新消息。

后端 poll-server.js 的代码如下:

const express = require('express');
const app = express();
let message = "No new message";

// 指定public文件夹是静态资源的目录
app.use(express.static("public"));

// 前端要轮询访问这个接口,这个接口会返回最新的message
app.get('/poll', (req, res) => {
  res.send(message);
  message = "No new message";
});

// 在其他地方调用这个接口,更新message
app.post('/update', (req, res) => {
  message = "Here's a new message!";
  res.status(200).send('Message updated');
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

前端 poll-client.html 则每隔几秒钟就发送一次请求,代码如下:

<script type="text/javascript">
setInterval(function() {
    fetch('/poll')
      .then(response => response.text())
      .then(data => {
        if (data !== "No new message") {
          console.log(data);
        }
      });
  }, 5000); // 每5秒请求一次
</script>

程序启动后,我们调用一次 /update,前端日志就会输出:Here's a new message!,否则就一直输出:No new message。

网页套接字(WebSocket)

原理

WebSocket是一种网络通信协议,它提供了全双工通信机制,它允许前后端建立一个持久的连接,并且双方都可以通过这个连接随时发送数据。就像打电话,双方可以随时说话和听对方说话。

优缺点

WebSocket 的优点在于它能够提供真正的实时通信,服务器和客户端都可以随时发送数据,而且相比轮询,它减少了HTTP请求的开销。但缺点是它的实现相对复杂,在弱网环境下可能不稳定,而且旧版的浏览器可能不支持 WebSocket。

适用场景

WebSocket 非常适合需要高实时性的场景,比如在线游戏、股票交易平台、实时聊天应用等。下面是使用WebSocket的一些真实案例:

  • Slack:这个流行的团队沟通工具使用WebSocket来实现实时消息传输。由于团队成员需要即时接收信息和通知,WebSocket的全双工通信机制提供了几乎零延迟的数据交换。
  • 多人在线游戏:许多现代的多人在线游戏使用WebSocket来同步玩家之间的状态。这种技术允许快速的数据传输,确保了游戏体验的流畅和实时互动。

代码示例

在Node.js中使用ws模块来创建一个WebSocket服务器:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3000 });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('something');
});

前端代码是这样的:

<script type="text/javascript">
const socket = new WebSocket('ws://localhost:3000');

socket.addEventListener('open', function (event) {
  socket.send('Hello Server!');
});

socket.addEventListener('message', function (event) {
  console.log('Message from server ', event.data);
});
</script>

运行这段程序之后,服务端会收到前端传递的 Hello Server!

前端会收到服务端发送的 something

服务器发送事件 (SSE)

原理

服务器发送事件(SSE)就像是一个广播站,当有新节目(数据)时,它就会向所有打开的收音机(客户端)发送信号。SSE 允许服务器主动向客户端发送数据流。与WebSocket不同的是,SSE 是单向通信,只能服务器向客户端发送数据。

优缺点

优点:与WebSocket比,实现更简单,只需要简单的HTTP协议就可以实现,并且支持自动重连;与轮询比,SSE可以减少服务器和客户端之间不必要的通信,服务器推送的方式更高效。

缺点:只支持单向通信(服务器到客户端);注意老旧浏览器可能不支持SSE(比如IE6、7、8、9)。

适用场景

SSE适用于不需要客户端向服务器发送消息的场景,比如股票价格的更新、新闻直播、或者任何只需服务器单向推送的实时数据显示。下面是使用SSE的一些真实案例:

  • ChatGPT:作为一个能够与用户进行互动的聊天机器人,ChatGPT使用服务器发送事件(SSE)来实现与用户的实时通信。ChatGPT在响应用户输入时,并不需要双向实时通信,它主要是接收用户的请求并返回计算结果。SSE可以在现有的HTTP基础设施上运行,这对于大规模服务而言,在连接管理和服务器资源分配方面可能更容易维护和优化。
  • 股票行情更新:许多金融网站使用SSE来推送实时股票价格和市场数据。由于股市信息需要实时更新,SSE为用户提供了一个不断流动的数据源,这样他们就可以看到最新的市场变化,而不必手动刷新页面。

代码示例

在Node.js中,我们可以使用如下方式创建一个SSE服务器,它每隔1秒向前端推送1条数据:

const express = require('express');
const app = express();

app.use(express.static("public"));

app.get('/events', function(req, res) {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  // 每隔1秒钟,写出1条数据
  setInterval(() => {
    res.write(`data: ${new Date().toLocaleTimeString()}\n\n`);
  }, 1000);
});

app.listen(3000, () => {
  console.log('SSE server running on port 3000');
});

客户端代码如下,它接收事件并打印消息:

<script type="text/javascript">
const evtSource = new EventSource('/events');

evtSource.onmessage = function(event) {
  console.log('New message:', event.data);
};
</script>

运行效果如下:


本文简要地介绍了三种主要的后端向前端推送数据的方式。每种技术都有自己的适用场景和优缺点,选择哪种技术取决于你的具体需求。不论你是在打造一个实时聊天应用,还是一个股票交易平台,这些技术都能帮助你提供更好的用户体验。

关注萤火架构,加速技术提升!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1434443.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

logback日志配置

springboot默认使用logback 无需额外添加pom依赖 1.指定日志文件路径 当前项目路径 testlog文件夹下 linux会在项目jar包同级目录 <property name"log.path" value"./testlog" /> 如果是下面这样配置的话 window会保存在当前项目所在盘的home文件夹…

arcgis各种版本下载

arcgic 下载&#xff01;&#xff01;&#xff01; ArcGIS是一款地理信息系统软件&#xff0c;由美国Esri公司开发。它提供了一系列完整的GIS功能&#xff0c;包括地图制作、空间数据管理、空间分析、空间信息整合、发布与共享等。ArcGIS是一个可扩展的GIS平台&#xff0c;提供…

详细了解ref和reactive.

这几天看到好多文章标题都是类似于&#xff1a; 不用 ref 的 xx 个理由不用 reactive 的 xx 个理由历数 ref 的 xx 宗罪 我就很不解&#xff0c;到底是什么原因导致有这两批人&#xff1a; 抵触 ref 的人抵触 reactive 的人 看了这些文章&#xff0c;我可以总结出他们的想法…

【PTA编程题】7-1 保持链表有序

对于输入的若干学生的信息&#xff0c;按学号顺序从小到大建立有序链表&#xff0c;最后遍历链表&#xff0c;并按顺序输出学生信息。 输入格式: 首先输入一个正整数T&#xff0c;表示测试数据的组数&#xff0c;然后是T组测试数据。每组测试数据首先输入一个正整数n&#xf…

OpenCV 图像处理六(傅里叶变换、模板匹配与霍夫变换)

文章目录 一、傅里叶变换1.1 NumPy实现和逆实现1.1.1 NumPy实现傅里叶变换Demo 1.1.2 NumPy实现逆傅里叶变换Demo 1.2 OpenCV实现和逆实现1.2.1 OpenCV实现傅里叶变换Demo 1.2.2 OpenCV实现逆傅里叶变换Demo 1.3 频域滤波1.3.1低频、高频1.3.2 高通滤波器构造高通滤波器Demo 1.…

ubuntu系统更改了/etc/fstab文件后无法进入系统,解决办法!

背景&#xff1a; ubuntu更改了/etc/fstab文件后&#xff0c;重启无法进入系统&#xff0c;比如设置硬盘自动挂载之类的。 说明&#xff1a; /etc/fstab是linux系统的文件系统表。 在进入系统前是通过检查此文件来加载相应的分区文件系统&#xff08;被记录到本文件中的所有文…

云服务器总结

1.服务器重装系后远程连接报错 Host key for xxx.xxx.xxx.xxx has changed and you have requested strict checking. 问题原因 ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时&#xff0c;OpenSSH会核对公钥。如果公钥不…

QT 范例阅读:系统托盘 The System Tray Icon example

main.cpp QApplication app(argc, argv);//判断系统是否支持 系统托盘功能if (!QSystemTrayIcon::isSystemTrayAvailable()) {QMessageBox::critical(0, QObject::tr("Systray"),QObject::tr("I couldnt detect any system tray ""on this system.&qu…

大卫·芬奇《消失的她》电影解读

《消失的爱人》&#xff08;Gone Girl&#xff09;是一部由大卫芬奇&#xff08;David Fincher&#xff09;执导的心理悬疑电影&#xff0c;改编自吉莉恩弗林&#xff08;Gillian Flynn&#xff09;的同名小说。这部影片于2014年上映&#xff0c;通过其精巧的剧本、紧张的氛围以…

深入解析与实践:基于VUE-cli的Element-UI应用指南

一、前言 ​ 本文介绍 Element-UI快速入门&#xff0c;基于vue-cli构建的基础项目。关于 vue-cli 构建项目的详细流程&#xff0c;可参考博文&#xff1a; 使用vue脚手架构建项目 二、简介 element-ui 是饿了么前端出品的基于 Vue.js的 后台组件库&#xff0c;方便程序员进行…

车位检测,YOLOV8,OPENCV调用

车位检测YOLOV8NANO,opencv调用 车位检测&#xff0c;YOLOV8NANO&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C,PYTHON,ANDROID

asqlcell,一个超强的 Python 库!

前言 大家好&#xff0c;今天为大家分享一个超强的 Python 库 - asqlcell。 Github地址&#xff1a;https://github.com/datarho/asqlcell Python asqlcell 是一个用于执行异步数据库操作的开源库&#xff0c;它允许开发者通过异步的方式与数据库进行交互&#xff0c;提高了数…

【数据分享】1929-2023年全球站点的逐年平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 之前我们分享过1929-2023年全球气象站点的逐年平均气温数据、逐年最高气温数据…

医学答案怎么查找?3个受欢迎的搜题分享了 #其他#职场发展#职场发展

学习工具是我们的得力助手&#xff0c;帮助我们更好地组织学习内容和时间。 1.南北题库 这是一个网站 完全免费,主要的特点就是题库全面丰富,涵盖计算机、外语、论文撰写、注册会计师等。并且后续还会继续扩展题库,题目分类非常详细,体界面清晰简洁。 有举一反三功能,搜一道…

【芯片设计- RTL 数字逻辑设计入门 6 -- 带同步复位的D触发器 RTL实现及testbench 验证】】

文章目录 带同步复位的D触发器Verilog 代码testbench 代码编译及仿真问题小结带同步复位的D触发器 同步复位 :复位只能发生在在clk信号的上升沿,若clk信号出现问题,则无法进行复位。 Verilog 代码 // timescale ins/1nsmodule flopr (input rstn,input clk,input[3:0]…

Linux--- vim详解

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 “学如逆水行舟&#xff0…

C#监听QQ消息自动回复-QQ自动化

整理 | 小耕家的喵大仙 出品 | CSDN&#xff08;ID&#xff1a;lichao19897314&#xff09; Q Q | 978124155 关于项目背景和微信自动化学习介绍 因为前面写了很多关于微信自动化的文章&#xff0c;网上有一位网友说他是做培训行业的&#xff0c;有时候除了微信对接客户还需要…

在Vue中如何动态绑定class和style属性

在Vue中&#xff0c;动态绑定class和style属性是我们经常遇到的需求。这个功能允许我们根据不同的条件来动态改变元素的样式&#xff0c;让我们的应用更加灵活和富有交互性。在本篇博客文章中&#xff0c;我将带你深入探索在Vue中如何实现这一功能。 首先&#xff0c;让我们了…

C语言内存函数:memcpy、memcat、memmove介绍和模拟实现(实用性高,建议三连收藏)

目录 1.memcpy函数 1.1函数介绍 1.2函数示范使用 1.3函数的模拟实现 1.4补充 2.memmove函数 2.1函数介绍 2.2函数的使用示范 2.3函数的模拟实现 3.memcmp(内存比较函数&#xff09; 3.1函数介绍 3.2函数的示范使用&#xff0c;有趣的例子 4.函数补充memset(内存…

SpringSecurity(18)——OAuth2授权码管理

AuthorizationCodeServices public interface AuthorizationCodeServices {//为指定的身份验证创建授权代码。String createAuthorizationCode(OAuth2Authentication authentication);//使用授权码。OAuth2Authentication consumeAuthorizationCode(String code)throws Invali…