服务器推送数据你还在用 WebSocket么?

在这里插入图片描述

当涉及到推送数据时,人们首先会想到 WebSocket。

的确,WebSocket 允许双向通信,可以自然地用于服务器到浏览器的消息推送。

然而,如果只需要单向的消息推送,HTTP 通过服务器发送的事件也有这种功能。

WebSocket 的通信过程如下:

首先,通过 HTTP 切换协议。服务器返回 101 状态码后,协议切换成功。

然后,开始以 WebSocket 格式的数据通信,任意一方都可以随时向另一方推送消息。

至于 HTTP 中的服务器发送的事件:

服务器返回的 Content-Typetext/event-stream,这是一种可以多次返回内容的流。

服务器发送的事件通过这种类型的消息随时推送数据。

你可能是第一次听说 SSE,但你已经使用过基于它的应用程序。

例如,你使用的 CI/CD 平台会实时打印日志。

那么它如何实时传输构建日志呢?

它需要分次传输,SSE 通常用于以这种方式推送数据。

另一个例子是 ChatGPT。它在回答问题时不会一次给你所有答案,而是逐步分块加载。

这也是基于 SSE 的。

现在我们已经知道 SSE 是什么以及它的应用,让我们自己实现它。

创建一个 Nest 项目。

npx nest new sse-test

运行它:

访问 http://localhost:3000 会显示“Hello World”,表示服务器运行成功。

然后在 AppController 中添加一个流接口。

这里没有用 @Get@Post 等装饰器进行标识,而是 @Sse 装饰器表示这是一个事件流类型的接口。

@Sse('stream')
stream() {return new Observable((observer) => {observer.next({ data: { msg: 'aaa'} });setTimeout(() => {observer.next({ data: { msg: 'bbb'} });}, 2000);setTimeout(() => {observer.next({ data: { msg: 'ccc'} });}, 5000);});
}

返回的是 Observable 对象,然后在内部使用 observer.next 返回消息。可以返回任何 JSON 数据。我们首先返回 aaa,2 秒后返回 bbb,5 秒后返回 ccc。然后创建一个前端页面:创建一个 React 项目。

npx create-react-app --template=typescript sse-test-frontend

App.tsx 中编写以下代码:

import { useEffect } from 'react';function App() {useEffect(() => {const eventSource = new EventSource('http://localhost:3000/stream');eventSource.onmessage = ({ data }) => {console.log('New message', JSON.parse(data));};}, []);return (<div>hello</div>);
}export default App;

这个 EventSource 是浏览器的原生 API,用于获取 SSE 接口的响应。它会将每个消息传入回调函数 onmessage 中。

我们在 Nest 服务中启用跨域支持。

然后删除 react 项目中的 index.tsx 文件中的这几行代码,因为它们会导致额外的渲染:

执行 npm run start

因为 3000 端口被占用,它将在 3001 上运行:

访问浏览器:

看到响应了吗?

这就是服务器发送的事件。

devtools 中,你可以看到响应的 Content-Typetext/event-stream

然后在 EventStream 中,你可以看到接收到的每条消息。

通过这种方式,服务器可以随时向网页推送消息。

它的兼容性如何?

你可以在 MDN 上看到。

除了 IE 和 Edge 外,与其他浏览器没有兼容问题。

一般来说,安全使用。

它可以在哪里使用?

服务器发送的事件 特别适合只需要服务器端推送的场景。

例如日志的实时推送。

让我们测试一下:

“tail -f”命令允许你实时查看文件的最新内容。

我们使用 child_process 模块的 exec 函数来执行这个命令,然后监听它的 stdout 输出。

const { exec } = require("child_process");const childProcess = exec('tail -f ./log');childProcess.stdout.on('data', (msg) => {console.log(msg);
});

使用 node 执行它。

然后添加一个 SSE 接口。

@Sse('stream2')
stream2() {
const childProcess = exec('tail -f ./log');return new Observable((observer) => {childProcess.stdout.on('data', (msg) => {observer.next({ data: { msg: msg.toString() }});})  
});

检测到新数据后,返回到浏览器。

浏览器连接到这个新接口:

测试如下:

可以看到浏览器已经接收到实时日志。

许多构建日志都是通过 SSE 实时推送的。

日志和类似的东西只是文本,但是如果是二进制数据呢?

在 Node.js 中,二进制数据存储在 Buffer 中。

const { readFileSync } = require("fs");const buffer = readFileSync('./package.json');console.log(buffer); 

Buffer 有一个 toJSON 方法:

这可以通过 SSE 接口返回吗?

试一下:

@Sse('stream3')  
stream3() {return new Observable((observer) => {const json = readFileSync('./package.json').toJSON();observer.next({ data: { msg: json }});});
}

的确可以。

换句话说,基于 SSE,除了可以推送文本,还可以推送任何二进制数据。

概括

可以使用 WebSocket 或 HTTP 的服务器发送事件(SSE)从服务器推送实时数据。

通过在 HTTP 响应中返回一个 Content-Type 为 text/event-stream 的头,可以通过流多次发送消息。

传输的内容是 JSON 格式,可以用来传输文本或二进制内容。

我们使用 Nest 实现了 SSE 接口。方法使用 @Sse 装饰器进行注释,它返回一个 Observable 对象。可以使用 observer.next 随时返回数据。

在前端,使用 EventSource 的 onmessage 来接收消息。

这个 API 在除 IE 和 Edge 外的其他浏览器有很好的兼容性,可以安全使用。

它有各种应用,如内部消息传递、构建日志的实时显示和 chatgpt 的消息响应。

当遇到需要消息推送的场景时,考虑使用服务器发送的事件而不是 WebSocket。

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

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

相关文章

驾驭数字孪生:智慧水利的未来之路

一、数字孪生技术的原理与实践 随着科技的不断进步&#xff0c;数字孪生技术作为一项创新的技术应用&#xff0c;正在逐渐改变我们的生活和工作方式。特别是在工业领域&#xff0c;数字孪生技术被视为实现智能制造、提升生产效率和产品质量的重要手段。本章节将深入探讨数字孪…

k8s的对外服务--ingress

service作用体现在两个方面 1、集群内部 不断跟踪pod的变化&#xff0c;更新endpoint中的pod对象&#xff0c;基于pod的IP地址不断变化的一种服务发现机制 2、集群外部 类似负载均衡器&#xff0c;把流量ip端口&#xff0c;不涉及转发url&#xff08;http&#xff0c;https&a…

npm依赖库备份

常用命令 设置默认使用本地缓存安装Nodejs时会自动安装npm&#xff0c;但是局路径是C:\Users\Caffrey\AppData\Roaming\npm默认的缓存路径是C:\Users\Caffrey\AppData\Roaming\npm-cache&#xff1b;查看npm的prefix和cache路径配置信息设置路径 设置默认使用本地缓存 npm con…

本周五上海见 第二届证券基金行业先进计算技术大会暨2024低时延技术创新实践论坛(上海站)即将召开

低时延技术是证券基金期货领域业务系统的核心技术&#xff0c;是打造极速交易系统领先优势的关键&#xff0c;也是证券基金行业关注的前沿技术热点。 1月19日下午&#xff0c;第二届证券基金行业先进计算技术大会暨2024低时延技术创新实践论坛&#xff08;上海站&#xff09;即…

springmvc上传与下载

文件上传 结构图 导入依赖 <dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId…

MySQL之视图索引

学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;SC (Sno, Cno, Score)…

VSCODE使用CMAKE显示命令无法找到

背景&#xff1a;使用了code server&#xff0c;安装CMAKE和CMAKE TOOLS&#xff0c;但是通过ctrlshiftp打开命令面板&#xff0c;运行随便一个cmake指令&#xff0c;都出现了指令无法找到。具体为“命令"CMake: 配置"导致错误 (command ‘cmake.configure’ not fou…

GPT APP的开发步骤

开发一个GPT&#xff08;Generative Pre-trained Transformer&#xff09; Store&#xff08;存储&#xff09;涉及到使用预训练的语言模型&#xff08;例如GPT-3&#xff09;来生成和管理内容。以下是一般的步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&…

探索设计模式的魅力:抽象工厂模式的艺术

抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;用于在不指定具体类的情况下创建一系列相关或相互依赖的对象。它提供了一个接口&#xff0c;用于创建一系列“家族”或相关依赖对象&#xff0c;而无需指定它们的具体类。 主要参…

[足式机器人]Part2 Dr. CAN学习笔记- Kalman Filter卡尔曼滤波器Ch05-1+2

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - Kalman Filter卡尔曼滤波器 Ch05-12 1. Recursive Algirithm 递归算法2. Data Fusion 数据融合Covarince Matrix协方差矩阵State Space状态空间方程 Observation观测器 1. Recursive Algirithm…

docker环境下mongo副本集的部署及异常修复

最近更换了办公地点。部署在本地docker环境里的mongo数据库不能使用了。原因是本地的ip地址变更。以前的mongo副本集的配置需要更新。处理完后&#xff0c;索性重新记录一下mongo副本集在docker中的部署流程。 mongo的事务及副本集 我们先了解一下什么是事务&#xff0c;事务…

selenium-java中切换iframe

1、当iframe中有固定的name或者id时可以通过name和id进行切换,代码如下 driver.switchTo().frame("name"); 2、当iframe中没有固定的name或者id时可以通过iframe角标进行切换&#xff0c;在浏览器通过ctrlf快捷键&#xff0c;搜索标签框输入//iframe;来查看当前ifr…

VsCode 常见的配置

转载&#xff1a;Visual Studio Code 常见的配置、常用好用插件以及【vsCode 开发相应项目推荐安装的插件】 - 知乎 (zhihu.com) 一、VsCode 常见的配置 1、取消更新 把插件的更新也一起取消了 2、设置编码为utf-8&#xff1a;默认就是了&#xff0c;不用设置了 3、设置常用的…

Chrome 开发者工具

Chrome 开发者工具 介绍控制面板时间线下载信息概要请求列表单个请求时间线优化时间线上耗时项 lighthouse 插件Performance&#xff08;性能指标&#xff09;Accessibility&#xff08;可访问性&#xff09;Best Practices&#xff08;最佳实践&#xff09;SEO&#xff08;搜索…

Luckysheet类似excel的在线表格(vue)

参考文档&#xff1a;快速上手 | Luckysheet文档 一、引入 在vue项目的public文件夹下的index.html的<head>标签里面引入 <link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/luckysheetlatest/dist/plugins/css/pluginsCss.css /><link relstylesheet hre…

Dockerfile镜像实战

目录 一 构建SSH镜像 1.开启ip转发功能 2. 准备工作目录 3.修改配置文件 5.启动容器并修改root密码 二 构建Systemctl镜像 1. 准备工作目录 ​编辑2.修改配置文件 3.生成镜像 4.启动容器&#xff0c;并挂载宿主机目录挂载到容器中&#xff0c;进行初始化 5.进入容器 三…

【Qt-license】误操作qt下载导致只能安装商业版试用十天,无法安装社区版

背景&#xff1a; 原本是为了学习qml&#xff0c;需要下载一个design studio&#xff0c;而这个需要比较新版的安装程序&#xff0c;但新版的安装程序官方都是online安装。于是从官网找下载链接。毕竟是英文的&#xff0c;又心急&#xff0c;误打误撞中我选择了商业版试用。 其…

大屏数据可视化的设计流程及原则

随着数字经济的快速发展和信息化在各行业各领域的深入推进&#xff0c;可视化大屏在各行各业得到越来越广泛的应用。可视化大屏不再只是电影里奇幻的画面&#xff0c;而是被实实在在地应用在政府、商业、金融、制造、交通、城市等各个行业的业务场景中&#xff0c;切切实实地实…

大模型日报-20240118

这里写目录标题 微软TaskWeaver开源框架&#xff1a;携手数据分析与行业定制&#xff0c;打造顶级Agent解决方案在24项场景中优于人类医生&#xff0c;Google团队开发基于自博弈的诊断对话大模型上海人工智能实验室团队开发具有多核光纤单元旋转功能的AI驱动投影断层扫描微软Co…

3DGS 其一:3D Gaussian Splatting for Real-Time Radiance Field Rendering

3DGS 其一&#xff1a;3D Gaussian Splatting for Real-Time Radiance Field Rendering 1. 预备知识1.1 球谐函数1.2 Splatting1.3 α \alpha α blending1.4 多维高斯的协方差矩阵1.4.1 高斯与椭球体的关系1.4.2 世界坐标系下的三维高斯到二维像素平面投影过程 2. 3D Gaussia…