为什么ChatGPT选择了SSE,而不是WebSocket?
我在探索ChatGPT的使用过程中,发现了一个有趣的现象:ChatGPT在实现流式返回的时候,选择了SSE(Server-Sent Events),而非WebSocket。
那么问题来了:为什么ChatGPT选择了SSE,而不是WebSocket呢。
SSE是什么?
SSE,全称Server-Sent Events,译为服务器发送事件,它是一种Web技术,允许服务器端实时地向客户端推送信息。SSE运行在HTTP协议之上,它利用持久化的HTTP连接,以事件流(Event Stream)的形式将数据发送给客户端,由客户端监听后获取。服务器端会定期向这个连接发送更新,这些更新被封装在一个或多个HTTP包中,每个包含有更新的事件流。这样,当有新的更新时,服务器就不需要等待客户端的请求,而是直接将数据推送给客户端。当连接被关闭或出现故障时,客户端会自动重新发送请求,重新建立连接。这确保了数据传输的连续性和实时性。
那么,SSE有什么优点呢?
- 单向通信:SSE只支持从服务器到客户端的单向通信,服务器可以主动发送数据,用户只能接收。
- 高效实时:因使用持久化连接,服务器可以实时地将数据推送给客户端,而无需客户端频繁发起请求。
什么是WebSocket?
WebSocket是一种网络通信协议,它最早被提出来是为了解决HTTP连接的一大限制:HTTP协议中,一个客户端发送给服务端的请求必须由服务端返回一个响应,这使得服务端无法主动向客户端推送数据。WebSocket的通信过程如下:
- 客户端通过发送一个特殊的HTTP请求向服务器请求建立WebSocket连接。这个请求类似于:GET /chat HTTP/1.1 Upgrade: websocket Connection: Upgrade
- 服务器响应这个请求,确认建立WebSocket连接。这个响应类似于:HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade
- 之后,客户端和服务器就可以通过这个常开的连接自由地发送或接收消息。
SSE与WebSocket的比较
你可能疑问,为什么不直接使用WebSocket,它似乎更为通用,也同样支持实时数据推送。这就是我们需要对比两者的理由。
- 通信模式:SSE只支持服务器向客户端的单向通信,而WebSocket支持全双工通信,即服务器和客户端可以互相发送数据。对于ChatGPT这样的应用来说,大多数情况下,用户的请求是稀疏的,而服务器的响应是密集的,因此,SSE的单向通信模式更为合适。
- 网络协议:SSE运行在HTTP协议上,因此,它可以提供更高的兼容性和灵活性。举个例子,如果你的产品已经部署在Web服务器上,那么你大概率无需做任何改动,就可以使用SSE技术。而WebSocket则需要单独的服务器和端口。
除此之外,SSE和WebSocket在消息大小、连接数量、跨域支持等方面都有一些细微的差别,我们在具体设计时需要根据实际需求和制约因素做出选择。
使用Golang和React实践SSE
首先,我们需要创建一个Golang服务器。这个服务器将监听8000端口,等待客户端的SSE连接请求,并定时向连接发送消息。为了简单起见,这里我们假设服务器每秒产生一条新消息。以下是Golang服务器的代码:
package main
import ("fmt""log""net/http""time"
)
func main() {http.HandleFunc("/events", func(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "text/event-stream")w.Header().Set("Connection", "keep-alive")w.Header().Set("Cache-Control", "no-cache")w.Header().Set("Access-Control-Allow-Origin", "*")
for {fmt.Fprintf(w, "data: Message at %s\n\n", time.Now())if flusher, ok := w.(http.Flusher); ok {flusher.Flush()} else {log.Println("Streaming unsupported!")return}time.Sleep(time.Second)}})http.Handle("/", http.FileServer(http.Dir("static")))log.Println("Listening on localhost:8000")http.ListenAndServe("localhost:8000", nil)
}
然后,我们需要创建一个React客户端,这个客户端会建立与Golang服务器的SSE连接,并在收到新消息时更新页面。以下是React客户端的代码:
import React, { useEffect, useState } from 'react';
function App() {const [events, setEvents] = useState([]);
useEffect(() => {const eventSource = new EventSource('http://localhost:8000/events');eventSource.onmessage = (event) => {setEvents((prevState) => [...prevState, event.data]);};}, []);
return (<div className="App"><h1>Live updates from server</h1>{events.map((event, i) => <p key={i}>{event}</p>)}</div>);
}
export default App;
这个应用程序将从服务器接收一个每秒更新一次的实时数据流,并在客户端将这些更新显示出来。
总结
通过以上的分析和代码示例,我们可以明白为什么ChatGPT会选择使用SSE而非WebSocket。请记住,无论选择哪种实时数据推送技术,必须考虑到你的应用程序的具体需求,例如数据更新的速度、服务器和客户端的能力、网络条件等等。
如果上面的内容对你有帮助,请点赞收藏哦,我会分享更多的经验~
相关文章:
为什么ChatGPT选择了SSE,而不是WebSocket?
我在探索ChatGPT的使用过程中,发现了一个有趣的现象:ChatGPT在实现流式返回的时候,选择了SSE(Server-Sent Events),而非WebSocket。 那么问题来了:为什么ChatGPT选择了SSE,而不是We…...

appium入门基础
介绍 appium支持在不同平台的UI自动化,如web,移动端,桌面端等。还支持使用java,python,js等语言编写自动化代码。主要用于自动化测试脚本,省去重复的手动操作。 Appium官网 安装 首先必须环境有Node.js用于安装Appium。 总体来…...

jsp介绍
JSP 一种编写动态网页的语言,可以嵌入java代码和html代码,其底层本质上为servlet,html部分为输出流,编译为java文件 例如 源jsp文件 <% page contentType"text/html; charsetutf-8" language"java" pageEncoding&…...
Debian安装k8s记录
Debian安装k8s记录 在master和node上安装kube安装master安装node遇到的问题汇总1、kubelet.service报错 failed to pull image "registry.k8s.io/pause:3.6"2、node重启后报错,failed: open /run/flannel/subnet.env: no such file or directory 在master…...

第6课 用window API捕获麦克风数据并加入队列备用
今天是2024年1月1日,新年的第一缕阳光已经普照大地,祝愿看到这篇文章的所有程序员或程序爱好者都能在新的一年里持之以恒,事业有成。 今天也是我加入CSDN的第4100天,但回过头看一看,这么长的时间也没有在CSDN写下几篇…...

图片预览 element-plus 带页码
vue3、element-plus项目中,点击预览图片,并显示页码效果如图 安装 | Element Plus <div class"image__preview"><el-imagestyle"width: 100px; height: 100px":src"imgListArr[0]":zoom-rate"1.2":max…...

【小白专用】winform启动界面+登录窗口 更新2024.1.1
需求场景:先展示启动界面,然后打开登录界面,如果登录成功就跳转到主界面 首先在程序的入口路径加载启动界面,使用ShowDialog显示界面, 然后在启动界面中添加定时器,来实现显示一段时间的效果,等…...

自动化网络故障修复管理
什么是故障管理 故障管理是网络管理的组成部分,涉及检测、隔离和解决问题。如果实施得当,网络故障管理可以使连接、应用程序和服务保持在最佳水平,提供容错能力并最大限度地减少停机时间。专门为此目的设计的平台或工具称为故障管理系统。 …...

Git:常用命令(二)
查看提交历史 1 git log 撤消操作 任何时候,你都有可能需要撤消刚才所做的某些操作。接下来,我们会介绍一些基本的撤消操作相关的命令。请注意,有些操作并不总是可以撤消的,所以请务必谨慎小心,一旦失误,…...

Oracle 12c rac 搭建 dg
环境 rac 环境 (主)byoradbrac 系统版本:Red Hat Enterprise Linux Server release 6.5 软件版本:Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit byoradb1:172.17.38.44 byoradb2:…...

Cisco模拟器-交换机端口的隔离
设计要求将某台交换机的端口划分在不同的VLAN。以实现连接在相同VLAN端口上的计算机可以通信,而连接在不同VLAN端口上的计算机无法通信的目的。 通过设计,一方面可以加强计算机网络的安全,另一方面通过隔绝不同VLAN间的广播包也可以提高网络…...
zdppy_api框架快速入门
概述 zdppy_api是一款为了快速开发而生的,基于异步的,使用简单的Python后端API接口开发框架。 本框架的目标是让Python后端开发变得越来越简单,直到发现原来还可以更简单! 一切都是为了提高开发效率!!&…...
https证书配置过程
相关网址: FreeSSL首页 - FreeSSL.cn一个提供免费HTTPS证书申请的网站 ACME v2证书自动化快速入门 acme.sh简单教程-CSDN博客...
如何用C语言程序生成任意手性(即具有任意m和n值),任意长度的碳纳米管,并输出三维空间坐标呢?
如何用C语言程序生成任意手性(即具有任意m和n值),任意长度的碳纳米管,并输出三维空间坐标呢? 生成任意手性、任意长度的碳纳米管可以使用 Chirality Vector 和 Unit Vector 的概念来表示。Chirality Vector (n, m) 描述…...

C++每日一练(8):图像相似度
题目描述 给出两幅相同大小的黑白图像(用0-1矩阵)表示,求它们的相似度。 说明:若两幅图像在相同位置上的像素点颜色相同,则称它们在该位置具有相同的像素点。两幅图像的相似度定义为相同像素点数占总像素点数的百分比。…...

C++面试宝典第12题:数组元素相除
题目 从控制台输入若干个整数作为数组,将数组中每一个元素除以第一个元素的结果,作为新的数组元素值。比如:可以先输入3,作为数组元素的个数;然后输入3个整数,作为数组元素的值。 解析 这道题本身并不复杂,但里面隐藏了不少“坑点”和“雷区”,主要考察应聘者全面思考问…...
oCPC实践录 | 目标ROI的出价与转化回传调控算法
这篇文章我们聊聊广告主在oCPC下,怎么调控自己的出价或者回传转化优化自己的ROI。 ROI是广告主最关心的指标了,根据oCPC出价的基本原理ocpc_bid pcvr * given_cpa * k, 广告主在整个出价中有两个可以控制的变量来影响出价,一个是直接的give…...
百倍量化之Dbcd-v2中性策略
Dbcd-v2中性策略 1. 指标含义 该指标主要是计算偏置的因子,并根据偏置的平均来分析这个股票的稳定性。相比于v1,策略是更换了dbcd的计算方式 第一步主要操作就是计算当前值和前段时间的平均值的偏置 ma = bt.indicators.SimpleMovingAverage(self.data, period=self.p.peri…...
系统学习Python——装饰器:函数装饰器-[装饰器状态保持方案:函数属性]
分类目录:《系统学习Python》总目录 如果我们没有在使用Python3.X并因此无法利用一条nonlocal语句,或者我们希望代码具有可移植性,能在Python3.X和Python2.X上同时工作一一我们仍然能够针对某些可改变的状态使用函数属性来避免使用全局变量和…...

逻辑卷学习后续----------缩容
一、缩容:缩减大小 ext4可以 , xfs无法缩减,缩减会影响业务 1.解挂载 2.检查文件系统完整性 3.缩减文件系统 4.缩减逻辑卷上下一致 5.再挂载回去 添加磁盘 文件系统只能装ext4 缩减文件系统 resize2fs 挂载失败需要重新安装文件系统…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...

实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...