网络-SSE

news2024/11/24 2:38:07

文章目录

  • 前言
  • 一、SSE简介
    • 1、SSE特点
      • Polyfill
    • 2、SSE原理
    • 3、SSE技术实现:
    • 4、SSE应用场景:
    • 5、EventSource
  • 二、SSE使用
    • 1、前端
    • 2、后端
    • 3、完整代码
      • 前端
      • 后端
  • 总结


前言

本文主要记录SSE通讯的简介、使用、以及原理和一个ChatGPT返回数据的demo。


一、SSE简介

SSE(Server-Sent Events,服务器推送事件)是一种用于在浏览器和服务器之间实现实时、单向通信的Web技术。它允许服务器向客户端推送数据,而无需客户端发起请求。与传统的HTTP请求-响应模式不同,SSE建立了一种持久的连接,通过这个连接,服务器可以随时向客户端发送更新的数据。这种实时通信的方式非常适用于需要实时更新数据的应用,如聊天应用、股票行情、实时监控等。

1、SSE特点

  • 简单易用:SSE使用简单的API,只需要创建EventSource对象并监听事件即可实现实时通信。
  • 单向通信:SSE是一种单向通信方式,只允许服务器向客户端推送数据,而不支持客户端向服务器发送请求。
  • 实时性:SSE建立了持久连接,服务器可以随时向客户端发送更新的数据,实现实时的数据推送。
  • 自动重连:如果连接中断,SSE会自动尝试重新建立连接,确保持久连接的稳定性。
  • 支持事件流:SSE使用事件流(event stream)的格式来传输数据,可以发送不同类型的事件,方便客户端进行处理。

需要注意的是,SSE在一些旧版本的浏览器中可能不被完全支持。但是,大多数现代浏览器都支持SSE,并且可以通过Polyfill来提供兼容性支持。

Polyfill

Polyfill是一种用于填充浏览器或环境中缺少的功能或API的代码。它可以在旧版本的浏览器或不支持某些新特性的环境中,提供对这些功能的兼容性支持。当新的Web标准或API被引入时,不同的浏览器或环境可能会以不同的速度进行支持和实现。在这种情况下,开发人员可以使用Polyfill来填充这些缺失的功能。

Polyfill通常是一个JavaScript库或脚本,它通过在运行时检测浏览器或环境的功能支持情况,然后根据需要动态地添加缺失的功能或API的实现。例如,如果某个浏览器不支持ES6的新特性,如箭头函数、模板字符串等,开发人员可以使用相应的Polyfill来提供对这些特性的支持。Polyfill会检测浏览器是否支持这些特性,如果不支持,则在运行时添加相应的代码来实现这些特性。

需要注意的是,Polyfill并不是一种通用的解决方案,它可能会增加页面的加载时间和代码体积。因此,在使用Polyfill时,需要根据具体的需求和目标浏览器进行选择和优化。

2、SSE原理

  • 客户端通过创建一个EventSource对象来与服务器建立连接。
  • 服务器通过发送特定格式的事件流(event stream)数据,将数据推送给客户端。
  • 客户端通过监听EventSource对象的事件,如message事件,来接收服务器发送的数据。
  • 服务器可以根据需要发送不同类型的事件,如message事件、open事件、error事件等。

3、SSE技术实现:

SSE基于HTTP协议,利用其长连接特性,通过浏览器向服务器发送一个HTTP请求,建立一条持久化连接。

4、SSE应用场景:

  • 实时数据大屏(这种不需要客户端做操作的,只需要服务端将数据不断给客户端,并且需要长时间连接,并不一定需要WebSocket
  • chatGPT 返回数据

5、EventSource

EventSource是HTML5中的一个API,用于在客户端与服务器之间建立基于HTTP的单向通信。

二、SSE使用

1、前端

  • 创建EventSource对象:
    在客户端的JavaScript代码中,使用new EventSource(url,options)来创建一个EventSource对象.
    • 其中url是服务器端的URL,必填。
    • options是配置项可选参数Object类型,常用配置包括:
      • withCredentials:Boolean类型,标识是否允许发送CoolieHTTP认证信息。默认false
      • headers:Object类型,标识发送的请求头信息。
      • retryInterval:Number类型,标识与服务器失去连接后,重连时间间隔。默认1000毫秒
 const sse = new EventSource('http://localhost:3000/api/sse',{
                withCredentials:false,
                headers:{},
                retryInterval: 1000
            })
  • 监听事件:
    通过为EventSource对象添加事件监听器,如onmessage、onopen、onerror等,来处理服务器发送的事件。
    • onmessage:表示已经收到服务端数据。
    • onopen:表示已经建立了连接,并开始接收服务端数据。当后端没有定义返回的事件,默认是该事件。
    • onerror:表示建立连接或接收数据时发生错误。
  • 接收事件:
    当服务器发送事件流数据时,EventSource对象会触发相应的事件,客户端可以通过事件监听器来接收和处理这些事件。
 sse.onopen = (e) =>{
                console.log('连接成功', e)
            }
            sse.onmessage = (e) =>{
                console.log('接收到数据', e)
            }
            sse.onerror= (e) =>{
                console.log('发生错误',e)
            }
            sse.addEventListener('message',(e)=>{
                const span = document.getElementById('animate')
                span.remove()
                message.innerHTML += `${e.data}<span id="animate">|</span>`
            })
  • 关闭连接:
    如果不再需要与服务器保持连接,可以调用EventSource对象的close()方法来关闭连接。
stop.addEventListener('click',(e)=>{
                console.log('断开连接',e)
                sse.close()
            })

2、后端

后端必须设置响应头 'Content-Type': 'text/event-stream',然后其他就和普通get请求一样。

后端是可以设置事件名称的,返回event 表示定义事件名称

res.write(`event:dg\n`)

3、完整代码

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .box{
        height: 100vh;
        width: 100%;
        background: #1B1A22;
    }
    #message{
        color: white;
    }
    #animate{
        display: inline-block;
        padding:0 5px;
        font-size:20px;
        font-weight: bold;
        animation: fade 1s infinite forwards;
    }
    @keyframes fade {
        from{
            opacity: 0;
        }
        to {
            opacity: 1;
        }
    }
</style>
<body>
<div>
    <div class="box">
        <div id="message"><span id="animate">|</span></div>
        <div style="margin-top: 30px"><button id="stop">断开连接</button></div>
    </div>
</div>
</body>
<script>
    const message = document.getElementById('message')
    const stop = document.getElementById('stop')
    document.addEventListener('keydown',(e)=>{
        if (e.keyCode == 13){
            const sse = new EventSource('http://localhost:3000/api/sse',{
                withCredentials:false,
                headers:{},
                retryInterval: 1000
            })
            sse.onopen = (e) =>{
                console.log('连接成功', e)
            }
            sse.onmessage = (e) =>{
                console.log('接收到数据', e)
            }
            sse.onerror= (e) =>{
                console.log('发生错误',e)
            }
            sse.addEventListener('message',(e)=>{
                const span = document.getElementById('animate')
                span.remove()
                message.innerHTML += `${e.data}<span id="animate">|</span>`
            })
            stop.addEventListener('click',(e)=>{
                console.log('断开连接',e)
                sse.close()
            })

        }
    })

</script>
</html>

后端

这里后端用Node

app.get('/api/sse',(req,res)=>{
    res.writeHead(200,{
        'Content-Type': 'text/event-stream',
        'Access-Control-Allow-Origin': '*'
    })
    // 读取本地文件
    const txt =  fs.readFileSync('../SSE/index.txt','utf8')
    // 分割成字符数组
    const arr = txt.split('')
    let currnet = 0
    let timer = setInterval(()=>{
        if (currnet < arr.length){
            // 设置返回事件名称
            // res.write(`event:dg\n`)
            res.write(`data:${arr[currnet]}\n\n`)
            currnet++
        }else{
            clearTimeout(timer)
        }
    },300)

})

SSE

注:
SSE是服务端主动向客户端发送数据,在客户端发送连接数据连接后,客户端就不能再向服务端发送数据了,只能服务端给客户端发送数据,这是因为SSE是单工通讯的。

只接受get请求

服务端没有设置正确的响应头信息,可能导致无法接收数据


总结

总的来说,SSE是一种简单、实时的通信技术,适用于需要实时推送数据的应用场景,提供了一种有效的方式来实现服务器向客户端的实时通信。

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

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

相关文章

专业图像处理软件DxO PhotoLab 7 mac中文特点和功能

DxO PhotoLab 7 mac是一款专业的图像处理软件&#xff0c;它为摄影师和摄影爱好者提供了强大而全面的照片处理和编辑功能。 DxO PhotoLab 7 mac软件特点和功能 强大的RAW和JPEG格式处理能力&#xff1a;DxO PhotoLab 7可以处理来自各种相机的RAW格式图像&#xff0c;包括佳能、…

Redis中Hash类的操作

Redis中Hash类型是键值对的形式保存数据&#xff0c;其中键被称为字段&#xff08;field&#xff09;&#xff0c;值称为字段值&#xff08;value&#xff09;。在一个key中&#xff0c;字段不能重复&#xff0c;而值可以重复。无论是字段还是值都是无序的&#xff08;保存的次…

React封装自定义表单校验方法

一、表单校验 为什么要封装自定义表单校验方法&#xff0c;因为在后台管理系统中&#xff0c;通常我们会涉及到用户的添加或则信息的修改&#xff0c;这时候通常就涉及表单的相关校验。但通常一个系统中的表单校验针对同一个字段来说是统一的。因此我们就需要将对应的校验字段的…

【LeetCode热题100】--98.验证二叉搜索树

98.验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 由于二…

41 二叉树的层序遍历

二叉树的层序遍历 题解1 迭代——BFS题解2 递归——DFS 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 提示&#xff1a; 树中节点数目在范围 [0, 2000] 内-1000 < Node.val <…

实时目标检测:基于YOLOv3和OpenCV的摄像头应用

一、前言 随着人工智能和计算机视觉技术的不断发展,目标检测成为了智能监控、自动驾驶、机器人等领域的关键技术之一。实时目标检测更是对系统的反应速度和准确度提出了更高的要求。本文介绍使用OpenCV和YOLOv3实现实时目标检测的方法,演示如何使用OpenCV调用YOLOv3模型进行…

基于SSM的选课排课系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

克服网络安全压力:如何掌控无限的云数据

管理云中的数字风险比以往任何时候都更加重要。数字化转型引发的云数据呈指数级增长&#xff0c;为安全分析师创造了一个更大的威胁环境。随着威胁行为者继续危害组织最敏感的数据&#xff0c;这一挑战将会加剧。 预计未来五年全球网络犯罪成本将激增&#xff0c;从 2022 年的…

22-框架

框架 解决某类问题&#xff0c;编写的一套类、接口等&#xff0c;可以理解成一个半成品&#xff0c;大多框架都是第三方研发的。 好处&#xff1a;在框架的基础上开发&#xff0c;可以得到优秀的软件架构&#xff0c;并能提高开发效率 框架的形式&#xff1a;一般是把类、接口…

有向图计数优化版原理及C++实现

题目 见前面章节。有向图访问计数的原理及C实现-CSDN博客 第一版 不需要拓扑排序&#xff0c;也不需要并集查找&#xff0c;直接dfs了。完成以下三个职责&#xff1a; 一&#xff0c;DFS那些端点在环上。 二&#xff0c;DFS环上各点此环的长度。 三&#xff0c;DFS非环上各点…

C# 画参数可调调幅波

参阅此&#xff0c; 使用VC输出调幅波的数值和波形_c如何显示下位机传输过来的频谱信号 csdn_bcbobo21cn的博客-CSDN博客 用winform做一下&#xff1b; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Dra…

16-自动化测试——selenium介绍

目录 1.selenium是什么&#xff1f; 2.selenium特点 3.selenium工作原理 1.selenium是什么&#xff1f; selenium是web应用中基于UI的自动化测试框架。 2.selenium特点 支持多平台多浏览器多语言&#xff08;Java、Python、C#、JS、Ruby......&#xff09;有丰富的API 3…

目标检测算法改进系列之Backbone替换为ConvNextV2

ConvNextV2 受掩码自编码机制的启发&#xff0c;本文在 ConvNeXt 的架构基础上延伸出了一个完全卷积掩码自编码器框架——ConvNeXt V2&#xff0c;同时作者设计了一个全新的全局响应归一化(Global Response Normalization, GRN)层以增强原始 ConvNeXt 模块通道间的特征竞争&am…

SpringBoot注册web组件

目录 前言 一、注册Servlet组件 1.1 使用SpringBoot注解加继承HttpServet类注册 1.2 通过继承HttpServet类加配置类来进行注册 二、注册Listener组件 2.1 使用SpringBoot注解和实现ServletContextListener接口注册 2.2 ServletContextListener接口和配置类来进行注册 …

基于YOLOv8的安全帽检测系统(2):Gold-YOLO,遥遥领先,助力行为检测 | 华为诺亚NeurIPS23

目录 1.Yolov8介绍 2.安全帽数据集介绍 3.Gold-YOLO 4.训练结果分析 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它建立在先前YOLO成功基础上…

js 如何判断一个指定的位置点坐标是否落在一个多边形区域内?

1 场景 业务场景举例&#xff1a;快递选择收获区域、车辆电子围栏、运动轨迹路线、地理位置信息检测范围和地图等过滤等等。   比方说地图上有一块区域&#xff08;抽象成多边形&#xff09;&#xff0c;然后里面每一个位置点(像素点)都有对应的GPS的经纬度坐标值&#xff0c…

如何破解压缩包zip解压密码?

Zip压缩包设置了密码&#xff0c;解压的时候就需要输入正确对密码才能顺利解压出文件&#xff0c;正常当我们解压文件或者删除密码的时候&#xff0c;虽然方法多&#xff0c;但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么&#xff0c;忘记了zip压缩包的密…

【C++】模板初阶 -- 详解

一、泛型编程 // 实现一个通用的交换函数&#xff1a; void Swap(int& left, int& right) {int temp left;left right;right temp; }void Swap(double& left, double& right) {double temp left;left right;right temp; }void Swap(char& left, ch…

Multisim14.0仿真(二十八)74LS13 施密特触发器

一、仿真原理图&#xff1a; 二、仿真效果图&#xff1a;

华为云云耀云服务器L实例评测|Elasticsearch的springboot整合 Kibana进行全查询和模糊查询

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到各种问题&#xff0c;在解决问题的过程中学到不少和运维相关的知识。 在前几期的博客中&#xff0c;介绍了Elasticsearch的Docker版本的安装&#xff0c;Elasticsearch的可视化Kibana工具…