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

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

本文聊聊前端获取实时数据的三种主要方式。想象一下,我们在网上购物时,经常能看到最新的优惠信息弹出,或者在社交媒体上看到朋友的最新动态更新。这些都是因为后端在默默地向我们的页面推送了最新的消息。那么,这背后到底使用了什么样的技术呢?主要有三种方式:轮询(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.mzph.cn/news/671032.shtml

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

相关文章

22.HarmonyOS App(JAVA)位置布局PositionLayout使用方法

不常用 在PositionLayout中&#xff0c;子组件通过指定准确的x/y坐标值在屏幕上显示。(0, 0)为左上角&#xff1b;当向下或向右移动时&#xff0c;坐标值变大&#xff1b;允许组件之间互相重叠 布局方式 PositionLayout以坐标的形式控制组件的显示位置&#xff0c;允许组件相…

【C++】win11,OpenCV安装教程(VS2022)

1.下载 首先进入官网&#xff0c;下载对应的安装包&#xff0c;苹果系统就选IOS pack&#xff0c;微软系统就选Windows 下载地址&#xff1a;Releases - OpenCV 不方便外网下载的话可以下载我分享的百度网盘资源&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1lV7l…

C语言条件判断:if、else、else if 和 switch 详解

在C语言中&#xff0c;条件判断是一种根据特定条件执行不同代码块的核心机制。为了更好地理解这一概念&#xff0c;本文将深入探讨C语言中的四种主要条件判断结构——if、else、else if和switch&#xff0c;并通过优化变量来展示其实际应用。 1. if 语句 if 语句用于基于某个…

rhel8静态ip配置

1.先cd进来 2.把默认的dhcp改成static IPADDR192.168.211.22 22随意改&#xff0c;255以下的数字都行&#xff0c;1和255不要用 GATEWAY192.168.211.2和虚拟机默认网关保持一致 重启网络 nmcli c reload和 nmcli c up ens160 ping百度测试--&#xff08;成功了&#xff0…

如何在Linux中安装新版的Python软件

一、引言 Python是目前世界上最为流行的编程语言&#xff0c;其在人工智能领域表现尤为出色。通常&#xff0c;我们为了测试github上面的一些项目&#xff0c;比如&#xff1a;chat-on-wechat&#xff0c; 我们就可以在vps上的Linux系统中安装Python&#xff0c;从而实现各种人…

CentOS镜像如何下载?在VMware中如何安装?

一、问题 CentOS镜像如何下载&#xff1f;在VMware中如何安装&#xff1f; 二、解决 1、CentOS镜像的下载 &#xff08;1&#xff09;官方网站 The CentOS Project &#xff08;2&#xff09;官方中文官网 CentOS 中文 官网 &#xff08;3&#xff09;选择CentOS Linux…

92.网游逆向分析与插件开发-游戏窗口化助手-显示游戏数据到小助手UI

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;游戏窗口化助手的UI设计-CSDN博客 码云地址&#xff08;游戏窗口化助手 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;e8116af3a7b0186adba…

汽车信息安全--SHE中的密钥管理(二)

目录 1.概述 2 SHE的数据存储和管理 3.小结 1.概述 上一篇我们讲解了HTA基本概念,SHE和EVITA HSM区别以及SHE的架构,接下来我们聊一聊SHE中的密钥管理策略。 2 SHE的数据存储和管理 由于SHE是硬件安全扩展,因此密钥和MAC值的存储需要使用SHE内部memory,每个密钥均搭配…

告警能力中台设计与实践(一)——策略制定

一、告警与通知 告警与通知是服务监控平台的主要输出&#xff0c;但二者是又一定差别的。 告警会在某些时间发生时&#xff08;如指标达到阈值&#xff09;时触发。然而&#xff0c;这并不一定意味着有人被告知此事件的发生&#xff09;这是通知的来源。 所谓通知&#xff0…

《Docker极简教程》--Docker基础--基础知识(三)

一、Namespace和Cgroups 1.1 Namespace的作用和类型 Docker 的 Namespace 是 Linux 内核提供的一种机制&#xff0c;用于隔离系统资源&#xff0c;使得容器能够拥有自己独立的视图&#xff0c;从而实现更高程度的隔离和安全性。Namespace 在 Docker 中扮演着至关重要的角色&a…

初识C语言·编译与链接

1 翻译环境和运行环境 C语言标准ANSI C 实现C语言代码的时候 一般需要经过两种环境&#xff0c;一是翻译环境&#xff0c;二是运行环境&#xff0c;计算机能识别的是二进制的指令&#xff0c;人写完代码后通过翻译环境&#xff0c;使代码变成计算机能读懂的可执行的机器指令&a…

机器人工具箱学习(一)

一、机器人工具箱介绍 机器人工具箱是由来自昆士兰科技大学的教授Peter Corke开发的&#xff0c;被广泛用于机器人进行仿真&#xff08;主要是串联机器人&#xff09;。该工具箱支持机器人一些基本算法的功能&#xff0c;例如三维坐标中的方向表示&#xff0c;运动学、动力学模…

极限方法大总结【高数笔记】

【方法步骤】 分几步&#xff1f;又有几个小步骤&#xff1f; 【不同类型的极限】 不同类型极限的方法又有哪些步骤&#xff1f; 不同类型极限的方法有哪些前提条件&#xff1f; 个别类型极限方法的技巧有哪些&#xff1f;

『运维备忘录』之 Yum 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

Droppy教程 | 轻量文件共享

文件共享成为了日常工作的重要组成部分。特别是对于那些需要快速、高效分享大文件的人来说&#xff0c;拥有一个简单可靠&#xff0c;且易于管理的平台至关重要。 项目地址&#xff1a;https://github.com/droppyjs/droppy 一、测试环境 uname -i # x86_64 docker -v # Docke…

年底个人总结

年底个人总结 前言&#xff1a;又到了年底&#xff0c;在游戏行业工作了接近10年&#xff0c;想想也应该把自己做过的东西做一个总结。 从14年在北京毕业&#xff0c;懵懂的我在机缘巧合下遇到了陈g&#xff0c;我行业的领路人&#xff0c;在他的带领下我进入到了游戏行业。 当…

[office] 在往Excel中录入数据时 #微信#学习方法#职场发展

在往Excel中录入数据时 在往Excel中录入数据时&#xff0c;有时会遇到大量的重复数据&#xff0c;比如有这么一个工作表&#xff0c;第一列显示任务名&#xff0c;第二列显示任务执行者&#xff0c;第三列显示执行者的性别&#xff0c;其中任务执行者为固定的几个人交替执行&am…

Bootstrap5 导航组件和面包屑

Bootstrap5 导航组件和面包屑 Bootstrap5 提供了一种简单快捷的方法来创建基本导航&#xff0c;它提供了非常灵活和优雅的选项卡和Pills等组件。 Bootstrap5 的所有导航组件&#xff0c;包括选项卡和Pills&#xff0c;都通过基本的 .nav 类共享相同的基本标记和样式。 使用 B…

深入探究:JSONCPP库的使用与原理解析

君子不器 &#x1f680;JsonCPP开源项目直达链接 文章目录 简介Json示例小结 JsoncppJson::Value序列化Json::Writer 类Json::FastWriter 类Json::StyledWriter 类Json::StreamWriter 类Json::StreamWriterBuilder 类示例 反序列化Json::Reader 类Json::CharReader 类Json::Ch…

【计算机二级考试C语言】C可变参数

C 可变参数 有时,您可能会碰到这样的情况,您希望函数带有可变数量的参数,而不是预定义数量的参数。 C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数。 声明方式为: int func_name(int arg1, ...); 其中,省略号 ... …