服务器往浏览器推消息(SSE)应用

news2025/1/20 5:46:04

1,SSE 和 WebSocket 对比

SSE(服务器发送事件)
SSE是一种基于HTTP的单向通信机制,用于服务器向客户端推送数据。它的工作原理如下:

建立连接:客户端通过发送HTTP请求与服务器建立连接。在请求中,客户端指定了接收事件的终点(Endpoint)。
保持连接:服务器接收到连接请求后,保持连接打开,并定期发送事件数据给客户端。
事件流:服务器使用 “Content-Type: text/event-stream” 头部标识SSE连接,并使用特定格式的数据(事件流)发送给客户端。
客户端处理事件:客户端通过JavaScript的 EventSource 接口监听SSE连接,一旦接收到事件,就可以处理数据并更新页面。
SSE的特点和适用场景:

单向通信:SSE是从服务器到客户端的单向通信模型,只能由服务器推送数据给客户端。
实时更新:SSE适用于需要实时更新数据的应用场景,如股票行情、新闻推送等。
简单易用:使用SSE相对简单,无需额外的库或框架支持,可以直接使用浏览器的原生API进行开发。

WebSocket
WebSocket是一种全双工的通信协议,它通过在客户端和服务器之间建立持久连接,实现双向通信。WebSocket的工作原理如下:

握手阶段:客户端向服务器发送WebSocket握手请求,服务器返回握手响应。在这个阶段,客户端和服务器协商选择协议和版本。
建立连接:握手成功后,客户端和服务器之间建立持久连接,可以进行双向数据传输。
双向通信:一旦连接建立,客户端和服务器都可以主动发送消息给对方。数据可以以文本或二进制格式进行传输。
断开连接:当任一方决定关闭连接时,可以发送关闭帧来终止连接。
WebSocket的特点和适用场景:

双向通信:WebSocket支持双向通信,客户端和服务器可以互相发送消息。
实时互动:WebSocket适用于实时互动的应用场景,如聊天应用、协作编辑等。
复杂性和灵活性:相对于SSE,WebSocket更为灵活,可以处理更复杂的通信需求。它允许自定义消息格式、心跳检测、连接状态管理等。
 

2,具体代码实现

2.1 后端

    @GetMapping(value = "/stock",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamStockPrice() {
        SseEmitter emitter = new SseEmitter();
        // 模拟生成实时股票价格并推送给客户端
        Random random = new Random();
        new Thread(() -> {
            try {
                while (true) {
                    // 生成随机的股票价格
                    double price = 100 + random.nextDouble() * 10;
                    // 构造股票价格的消息
                    String message = String.format("%.2f", price);
                    // 发送消息给客户端
                    emitter.send(SseEmitter.event().data(message));
                    // 休眠1秒钟
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        }).start();
        return emitter;
    }

2.2 前端

    $("#btn12").click(function (){
        const eventSource = new EventSource('http://localhost:8080/test/test/stock');
        eventSource.onmessage = function (event) {
            showMsg(event.data)
        }
    })

 2.3 最终效果

SSE 演示

3,传统部署方式

nginx部署

4,k8s部署方式

待研究

5,问题

问题 1:采用 nginx 部署时,页面刷新很慢,实际上服务器已经发了很多数据过来。

此问题待研究解决。

解决方法:

nginx 做相关配置

配置如下

         location /codeTest {
            proxy_pass http://127.0.0.1:18080/test;

            # proxy_http_version设置代理使用的HTTP协议版本为1.1。
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            # SSE 连接时的超时时间
            proxy_read_timeout 86400s;

            # 取消缓冲
            proxy_buffering off;
            # 关闭代理缓存
            proxy_cache off;
            # 禁用分块传输编码
            #chunked_transfer_encoding off
        }

/codeTest是你希望使用的路径,你可以根据需要进行修改。 proxy_pass指定了后端服务器的地址,你需要将其替换为实际的后端服务器地址。
proxy_http_version设置代理使用的HTTP协议版本为1.1。
proxy_set_header设置一些必要的头部信息,如连接方式、真实客户端IP等。
proxy_read_timeout 指令来设置 SSE 连接的超时时间。默认情况下,Nginx 会在 60 秒后关闭空闲的连接,这对于 SSE 来说是不合适的,所以我们将超时时间设置为一天(86400 秒)。这样,客户端和服务器之间的连接可以持续保持打开状态。
proxy_buffering off 指令来确保数据可以实时传输,而不需要等待缓冲区满。在SSE请求中禁用缓冲,以便正确处理SSE流式数据。
proxy_cache 对于 SSE(Server-Sent Events)连接,通常不建议启用 Nginx 的代理缓存(proxy_cache)。因为 SSE 是一种长连接技术,它通过保持持久连接来实时推送数据给客户端,而代理缓存会将响应数据缓存起来并在后续请求中返回缓存的响应,这与 SSE 的工作方式相违背。如果启用代理缓存,Nginx 可能会缓存 SSE 的数据,并在后续的连接中返回相同的缓存数据,这样会导致客户端收到重复的消息,破坏了 SSE 的实时性和准确性。
chunked_transfer_encoding 参数可以根据你的需求决定是否关闭。在 SSE 中,通常不需要禁用分块传输编码,因为它允许将数据以数据块的形式逐步传输,与 SSE 的流式数据特性相符合。
proxy_pass 指令正确反向代理到你的 SSE 应用程序的地址和端口,以使连接正确工作。

问题 2:连接一段时候,自动断开

解决方法参考如下文章

Springboot调整接口响应返回时长(解决响应超时问题)

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

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

相关文章

【linux API 分析】register_chrdev

linux kernel:4.19 在注册字符设备的时候,可使用register_chrdev()函数,其对应的注销函数是unregister_chrdev(),其定义是在include\linux\fs.h文件 register_chrdev() 首先分析register_chrdev()函数 其定义如下 static inlin…

SMAP(Soil Moisture Active and Passive)数据下载

SMAP(Soil Moisture Active and Passive)数据下载 打开网站先注册登录用户 然后打开SMAP下载的网站 点击HTTPS File System进入下载页面 然后点击HDF文件下载 下载之后在HDF View里面预览

Spring中反转控制与依赖注入

目录 一、反转控制(IOC) 二、依赖注入(DI) 一、反转控制(IOC) 在以前的学习中为成员变量的赋值,一般都是直接在代码中完成,但是这种方式会产生耦合。然而利用Spring对成员变量赋值可…

QT学习day2

一、思维导图 作业: 使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数将登录按钮使用qt5版本的连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admi…

sublime怎么调中文?

Sublime Text是一个功能强大的文本编辑器,它被广泛使用于编码过程中。在开发过程中,Sublime Text界面的语言设置通常默认为英语,无法直接输入中文。那么如何调整Sublime Text编辑器的设置,以允许在界面中输入和编辑中文呢&#xf…

CSS盒子模型的详细解析

03-盒子模型 作用:布局网页,摆放盒子和内容。 盒子模型-组成 内容区域 – width & height 内边距 – padding(出现在内容与盒子边缘之间) 边框线 – border 外边距 – margin(出现在盒子外面) d…

计算机网络学习笔记(三):数据链路层(待更新)

目录 3.1 基本概念 3.1.1 数据链路和帧 3.1.2 三个基本问题 3.2 类型1:使用点对点信道的数据链路层(路由器) 3.2.1 点对点协议 PPP:特点 3.2.2 点对点协议 PPP:帧格式 3.2.3 点对点协议 PPP:工作状态 …

了解web基础,http协议

域名 例如:www.baidu.com dns域名: 网络上的通信都是基于ip,通信模式:TCP/IP Tcp建立连接和断开连接,都是要双方进行确认的 建立连接:三次握手 断开连接:四次挥手 通信时端到端 端口进行通…

ONLYOFFICE 文档 7.5 现已发布:新增 PDF 编辑器、屏幕朗读器等功能

我们已推出最新版的在线编辑器,整个套件具备多项增强功能。敬请继续阅读,了解所有更新。 全新 PDF 编辑器 PDF 是工作中很常见的文件格式。 我们经常需要打开各种PDF格式的宣传册,签署协议和合同等等。 我们一直记得这一点,一直…

NR SRS power control

这篇看下NR SRS power control的相关内容,主要内容集中在38.213 7.3章节,SRS power control与PUSCH很类似,当然细节上也有所不同,这里简单看下。 UL功率控制,主要是PUSCH/PUCCH/SRS/PRACH的传输功率。 对于所有PUSCH/PUCCH/SRS传输…

掌握.NET基础知识(一)

前言 本文将讲解一些.NET基础。NET基础是指在计算机编程中使用.NET框架所需要的基础知识..NET的认识: .NET是由微软开发的一个跨平台的应用程序开发框架。它包括一个运行时环境和一个面向对象的程序库,可以用于开发各种类型的应用程序,包括桌面应用程序、…

计算机操作系统-第十天

目录 1、操作系统的进程 进程的概念 进程的组成------PCB 进程的组成------程序段、数据段 旧知新学:《程序是如何运行的》 进程的特征 本节思维导图 1、操作系统的进程 进程的概念 当我们打开多个qq程序,我们会发现任务管理器的进程中有…

对代码感兴趣 但不擅长数学怎么办——《机器学习图解》来救你

目前,该领域中将理论与实践相结合、通俗易懂的著作较少。机器学习是人工智能的一部分,很多初学者往往把机器学习和深度学习作为人工智能入门的突破口,非科班出身的人士更是如此。当前,国内纵向复合型人才和横向复合型人才奇缺;具有…

C#中使用 ref

下面是一个示例,演示了如何在C#中使用 ref: class Program {static void Main(){int number 10;Console.WriteLine("原始值: " number);ModifyValue(ref number);Console.WriteLine("修改后的值: " number);}static void Modify…

关于罗克韦尔跟西门子PLC之间通讯的解决方案

不同品牌的PLC设备之间通讯一般是通过总线模块,或者直接在PLC内编程实现,这样不仅硬件成本高,而且开发调试的时间都很长,后期维护也相当麻烦。本文采用IGT-DSER智能网关模块,PLC内不用编程,通过PLC现有的以…

如何在 Python 中创建一个虚拟环境,以及为什么需要它

当用 Python 开发软件时,一个基本的方法是在你的机器上安装 Python,通过终端安装所有需要的库,在一个 .py 文件或笔记本中编写所有的代码,并在终端运行你的 Python 程序。 这是很多初学者和很多从使用 Python 进行数据分析过渡的…

【Note】CNN与现代卷积神经网络part4(附PyTorch代码)

文章目录 2.2 残差网络(ResNet)2.2.1 函数类2.2.2 残差块2.2.3 ResNet模型2.2.4 训练模型2.2.5 Summary 本《CNN与现代卷积神经网络》Note系列会共分为4个part,本文为part4。本Markdown共4k字。 2.2 残差网络(ResNet) …

文心一言 4.0 ERNIE-Bot 4.0 :ERNIE-Bot 4.0 大模型深度测试体验报告

本心、输入输出、结果 文章目录 文心一言 4.0 ERNIE-Bot 4.0 :ERNIE-Bot 4.0 大模型深度测试体验报告前言相关跳转文心一言 4.0 ERNIE-Bot 4.0 接口简介Bash 请求示例代码Windows 模式使用 Python 请求如果直接使用官方提供的代码文心一言 4.0 ERNIE-Bot 4.0 API 在…

GEE19:基于Landsat8的常见的植被指数逐年获取

植被指数逐年获取 1. 常见的植被指数1.1 比值植被指数(Ratio vegetation index,RVI)1.2 归一化植被指数(Normalized Difference Vegetation Index,NDVI)1.3 增强植被指数(Enhanced Vegetation I…

nuxt3+ts:集成 百度-爱番番 客服

一、本文目标 nuxt3 ts 集成百度爱番番(客服) 百度爱番番—企业的一站式智能营销管家 二、百度爱番番客服能力 三、爱番番后台基础配置 3.1、设置中心 登录后点右上角设置中心 3.2、沟通与触达 -- > 站点设置 -- > 新建站点 填写信息 3.3、获…