百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

ChatGPT 对话使用的 EventSource 技术到底是什么?

zhezhongyun 2025-02-21 16:16 14 浏览

EventSource(又称为 Server-Sent Events,SSE)是一种在 Web 应用程序中实现服务器推送(服务器向客户端推送实时数据)的技术。是 HTML5 的一部分,实现了服务器向客户端推送数据,而不需要客户端不断地轮询服务器以获取最新数据。相较于 WebSocket 这样的全双工通信协议,EventSource 设计更为简单,特别适用于仅需服务器向客户端推送数据的场景,比如实时消息通知、股票报价更新、社交软件的新消息提示等。

文章持续更新中,微信搜索【路多辛】阅读更多优质文章

什么是 EventSource

EventSource 是 HTML5 中引入的一项技术,定义了一种从服务器到客户端的单向数据传输机制。EventSource 的核心思想是实现服务器端主动推送数据到客户端,而无需客户端频繁发起请求。基于 HTTP 长轮询技术,但与传统的轮询相比,具有更高的效率和实时性,因为一旦连接建立,服务器可以连续发送多个事件到客户端,直到连接关闭。

EventSource 工作原理

EventSource 基于 HTTP 协议,但与传统的 HTTP 请求不同,EventSource 创建了一个持久的连接,这个连接会一直保持打开状态,直到被客户端或服务器明确关闭。服务器可以通过这个连接随时发送新的数据。

  1. 建立连接:客户端通过 JavaScript 创建一个 EventSource 对象,指定要连接的服务器端点(URL)。通常是一个特殊的后端处理程序,负责生成并发送实时数据流。例如:
var source = new EventSource('http://example.com/events');

这个 source 对象会向指定的 URL 发送一个 HTTP GET 请求。服务器响应这个请求,并保持连接打开,以便发送后续的数据更新。

  1. 数据传输:服务器响应这个请求,并保持连接打开状态,而不是像普通 HTTP 请求那样发送完响应就关闭连接,响应需要设置为 text/event-stream 类型。之后,服务器可以随时发送数据到客户端,以两个换行符结尾,客户端的 EventSource 对象会接收到这个数据块作为一个事件。一个典型的服务器发送的事件可能是这样的:
data: This is a message\n\n

客户端的 EventSource 对象在收到这个数据块后,会触发一个 message 事件。

  1. 事件处理:客户端接收到事件后,EventSource 对象会触发相应的事件处理器(如 onmessage, onopen, onerror),开发者可以通过这些处理器处理接收到的数据。例如:
source.onmessage = function(event) {
	console.log("New message:", event.data);
};

服务器还可以发送命名的事件,客户端可以监听这些特定的事件:

event: userconnect
data: {"username": "Alice"}

在客户端,可以这样监听这个命名事件:

source.addEventListener('userconnect', function(event) {
	var data = JSON.parse(event.data);
	console.log(data.username + " connected");
});
  1. 断线重连:如果连接意外中断,EventSource 对象会自动尝试重新建立连接,除非明确被关闭或者达到最大重试次数。默认情况下,重连会在断开连接后立即发生。如果服务器想要通知客户端在一段时间后重连,可以包含一个 retry 字段:
retry: 10000\n
data: Please wait 10 seconds before reconnecting\n\n

告诉客户端在10秒后尝试重新连接。

EventSource 的优势

  • 简单轻量:EventSource 的实现和 API 都非常简单,对服务器压力小,不需要复杂的握手过程,易于理解和使用。
  • 自动重连:提供内置的断线重连机制,提高可靠性。
  • 易于部署:基于标准的 HTTP 协议,无需更改服务器配置即可使用。
  • 单向通讯:适合于只需要服务器推送数据的应用场景,简化了客户端逻辑。

EventSource 的局限性

  • 不支持二进制数据:只能发送文本数据。
  • 单向通信:只能从服务器到客户端发送数据,不能从客户端向服务器发送。

EventSource 的使用场景

  • 实时通知:比如社交媒体的实时更新、新闻网站的实时报道等。
  • 股票或货币行情更新:金融应用中的实时价格更新。
  • 在线聊天应用:虽然是单向的,但可以结合其他技术实现双向通信。
  • 游戏状态更新:在在线游戏中推送游戏状态的更新。

示例代码

客户端代码(html+js):




  
  EventSource Example


  

Server-sent Events Example

服务端代码(Golang):

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"
)

func main() {
	http.HandleFunc("/events", eventsHandler)
	log.Println("Server started on :8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

func eventsHandler(w http.ResponseWriter, r *http.Request) {
	// 设置响应头
	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")
	w.Header().Set("Access-Control-Allow-Origin", "*")

	// 发送事件数据
	for {
		timeMsg := fmt.Sprintf("data: The server time is %v\n\n", time.Now())
		w.Write([]byte(timeMsg))
		flusher, ok := w.(http.Flusher)
		if !ok {
			log.Println("Streaming unsupported!")
			return
		}
		flusher.Flush()
		time.Sleep(1 * time.Second)
	}
}

小结

EventSource 是一个强大又简单的 API,为开发者提供了一种在 Web 应用中实现服务器到客户端的实时通信的方法。尽管有很多局限性,但在适当的场景下是一个非常有用的工具。

文章持续更新中,微信搜索【路多辛】阅读更多优质文章



相关推荐

JPA实体类注解,看这篇就全会了

基本注解@Entity标注于实体类声明语句之前,指出该Java类为实体类,将映射到指定的数据库表。name(可选):实体名称。缺省为实体类的非限定名称。该名称用于引用查询中的实体。不与@Tab...

Dify教程02 - Dify+Deepseek零代码赋能,普通人也能开发AI应用

开始今天的教程之前,先解决昨天遇到的一个问题,docker安装Dify的时候有个报错,进入Dify面板的时候会出现“InternalServerError”的提示,log日志报错:S3_USE_A...

用离散标记重塑人体姿态:VQ-VAE实现关键点组合关系编码

在人体姿态估计领域,传统方法通常将关键点作为基本处理单元,这些关键点在人体骨架结构上代表关节位置(如肘部、膝盖和头部)的空间坐标。现有模型对这些关键点的预测主要采用两种范式:直接通过坐标回归或间接通过...

B 客户端流RPC (clientstream Client Stream)

客户端编写一系列消息并将其发送到服务器,同样使用提供的流。一旦客户端写完消息,它就等待服务器读取消息并返回响应gRPC再次保证了单个RPC调用中的消息排序在客户端流RPC模式中,客户端会发送多个请...

我的模型我做主02——训练自己的大模型:简易入门指南

模型训练往往需要较高的配置,为了满足友友们的好奇心,这里我们不要内存,不要gpu,用最简单的方式,让大家感受一下什么是模型训练。基于你的硬件配置,我们可以设计一个完全在CPU上运行的简易模型训练方案。...

开源项目MessageNest打造个性化消息推送平台多种通知方式

今天介绍一个开源项目,MessageNest-可以打造个性化消息推送平台,整合邮件、钉钉、企业微信等多种通知方式。定制你的消息,让通知方式更灵活多样。开源地址:https://github.c...

使用投机规则API加快页面加载速度

当今的网络用户要求快速导航,从一个页面移动到另一个页面时应尽量减少延迟。投机规则应用程序接口(SpeculationRulesAPI)的出现改变了网络应用程序接口(WebAPI)领域的游戏规则。...

JSONP安全攻防技术

关于JSONPJSONP全称是JSONwithPadding,是基于JSON格式的为解决跨域请求资源而产生的解决方案。它的基本原理是利用HTML的元素标签,远程调用JSON文件来实现数据传递。如果...

大数据Doris(六):编译 Doris遇到的问题

编译Doris遇到的问题一、js_generator.cc:(.text+0xfc3c):undefinedreferenceto`well_known_types_js’查找Doris...

网页内嵌PDF获取的办法

最近女王大人为了通过某认证考试,交了2000RMB,官方居然没有给线下教材资料,直接给的是在线教材,教材是PDF的但是是内嵌在网页内,可惜却没有给具体的PDF地址,无法下载,看到女王大人一点点的截图保...

印度女孩被邻居家客人性骚扰,父亲上门警告,反被围殴致死

微信的规则进行了调整希望大家看完故事多点“在看”,喜欢的话也点个分享和赞这样事儿君的推送才能继续出现在你的订阅列表里才能继续跟大家分享每个开怀大笑或拍案惊奇的好故事啦~话说只要稍微关注新闻的人,应该...

下周重要财经数据日程一览 (1229-0103)

下周焦点全球制造业PMI美国消费者信心指数美国首申失业救济人数值得注意的是,下周一希腊还将举行第三轮总统选举需要谷歌日历同步及部分智能手机(安卓,iPhone)同步日历功能的朋友请点击此链接,数据公布...

PyTorch 深度学习实战(38):注意力机制全面解析

在上一篇文章中,我们探讨了分布式训练实战。本文将深入解析注意力机制的完整发展历程,从最初的Seq2Seq模型到革命性的Transformer架构。我们将使用PyTorch实现2个关键阶段的注意力机制变...

聊聊Spring AI的EmbeddingModel

序本文主要研究一下SpringAI的EmbeddingModelEmbeddingModelspring-ai-core/src/main/java/org/springframework/ai/e...

前端分享-少年了解过iframe么

iframe就像是HTML的「内嵌画布」,允许在页面中加载独立网页,如同在画布上叠加另一幅动态画卷。核心特性包括:独立上下文:每个iframe都拥有独立的DOM/CSS/JS环境(类似浏...