96SEO 2026-05-06 13:47 0
Zui近在折腾几个AI编程相关的辅助工具时我观察到一个特别有意思的现象:当你向ChatGPT或者类似的AI大模型提问时屏幕上那些文字并不是像挤牙膏一样“噗”地一下全部蹦出来的,而是像有个隐形的人在键盘上实时敲击一样,一个字一个字地流淌出来。

这种体验,说实话,真的非常丝滑。但作为一个技术控,我脑子里冒出的第一个念头不是“哇,好神奇”,而是——这玩意儿底层是怎么实现的?
要知道,我们Zui熟悉的HTTP协议,本质上是个“一问一答”的愣头青。你发个请求,它回个包,然后这事儿就算完了连接也断了。Ru果AI要等全部生成完再一次性发回来那用户估计早就盯着白屏把鼠标戳烂了。所以这里肯定用到了某种流式传输的技术。
顺着这个思路往下挖,你会发现Web开发领域里关于“实时通信”的方案其实五花八门。但归根结底,Zui绕不开的三座大山就是:HTTP、SSE和WebSocket。
hen多同学在面试或者架构选型时经常对着这三个词发懵:它们不dou是TCP吗?到底有啥本质区别?今天我就结合我Zui近的研究心得,用Zui通俗的方式,把这层窗户纸给大家捅破。
一、HTTP:那个“你问我答”的老实人先说说HTTP。这可是互联网的基石,咱们每天刷网页、kan图片,全靠它。
HTTP协议的核心逻辑非常简单,简单到有点“轴”。它就像是一个严格的问答游戏:客户端必须先发起请求,服务端才Neng给回应。服务端绝对不Neng主动跑过来找客户端说话,哪怕服务器着火了只要客户端不发请求,服务器就得憋着。
1.1 短连接的痛在HTTP/1.1之前,每次请求dou是一次新的TCP连接。你想想,这得多累?
客户端 服务端
│ │
│─── GET /api/user/info ───>│ ← 发起请求
│ │ ← 服务端处理
│<── { "name":"张三" } ──│ ← 返回响应
│ │
│ TCP 连接关闭 │ ← 拜拜了您嘞
你kan,这流程就像寄信。你寄出一封信,邮差送过去,对方处理完,再寄回一封信,这事儿就算结了。Ru果你想再问个事儿,对不起,得重新走一遍流程。
虽然HTTP/1.1引入了Keep-Alive,Ke以让TCP连接复用,不用频繁握手,但语义层面上,它还是得等一个请求完了才Neng发下一个。这就导致了一个hen尴尬的问题:服务端想主动推送消息怎么办?
为了实现“实时”,早期的程序员想出了一个损招:轮询。
意思就是客户端像个急躁的孩子,每隔几秒钟就跑去问服务器一次:“好了没?好了没?有新消息没?”
前端 后端
│── GET /build/status ────>│
│<──── "building" ─────────│
│ │
│── GET /build/status ────>│
│<──── "building" ─────────│
│ │
│── GET /build/status ────>│
│<──── "success" ──────────│ ← 终于完成了
│ 停止轮询,刷新预览 │
本质客户端定时发HTTP请求问“好了没?”
优点实现极简,一个setInterval加一个GET接口就Neng跑,兼容性无敌。
缺点这简直是在浪费生命!大部分时间里服务器dou会回“没好呢”,这些请求就是无效的空跑,既浪费带宽又浪费服务器CPU。Ru果频率高了服务器扛不住;频率低了实时性又差。真是进退两难。
二、SSE:服务端单向推送的“广播台”既然轮询这么蠢,那有没有办法让服务器“一直说”呢?这就轮到SSE登场了。
SSE是HTML5引入的一个标准。它的名字其实Yi经把功Neng写在脸上了:服务端发送事件。这是一种基于HTTP的单向推送技术。
2.1 它是怎么工作的?SSE的思路非常巧妙:它利用了HTTP协议的一个特性——响应不结束。
普通的HTTP请求,服务器发完数据就会关闭连接。但SSE不一样,服务器发完响应头后故意不关闭连接,而是保持TCP通道畅通。然后服务器就像往水管里注水一样,想什么时候往里写数据,就什么时候写。
客户端 服务端
│ │
│── GET /api/stream ─────────────>│ ← 普通 HTTP GET
│ │
│<── 200 OK │
│ Content-Type: text/event-stream
│ Transfer-Encoding: chunked │ ← 响应头,不关闭连接
│ │
│<── data:{"d":"你"} │ ← 第 1 块数据
│<── data:{"d":"好"} │ ← 第 2 块数据
│<── data:{"d":"世"} │ ← 第 3 块数据
│<── data:{"d":"界"} │ ← 第 4 块数据
│ ... │ ← 持续推送
│<── event:done │ ← 结束事件
│ data: │
│ │
│ TCP 连接关闭 │ ← 服务端主动关闭
你kan,这条TCP连接活了足足几十秒,期间服务端不断往里写数据,客户端的浏览器收到数据就触发回调,根本不需要用户去刷新或者重新请求。
2.2 为什么AI生成特别爱用SSE?回到文章开头说的AI场景。用户发一条消息,AI逐字返回。这是一个典型的“一问、多答”的模式。
Ru果用WebSocket,虽然也NengZuo,但有点杀鸡用牛刀。因为AI生成内容时用户通常只需要kan着它输出,不需要在它生成到一半时突然插嘴说“停,换个话题”。这种单向流式输出,简直就是为SSE量身定Zuo的。
SSE规定了一个极简的纯文本格式,长得像这样:
data: 第一行
data: 第二行
或者带事件名:
event: build_complete
data: {"status": "success"}
这种格式解析起来非常快,对浏览器的负担极小。
2.3 SSE的优缺点优点:
实现简单: 服务端只需要返回特定的MIME类型text/event-stream,前端用EventSource几行代码就Neng搞定。
自动重连: 浏览器原生的EventSource对象非常贴心,Ru果断线了它会自动尝试重连,省去了开发者写重连逻辑的麻烦。
纯文本: 调试方便,直接kan抓包工具就Nengkan懂内容。
缺点:
单向通信: 只Neng服务器推给客户端。客户端Ru果想再发消息,还得再走一个HTTP请求。
文本限制: 虽然也Neng传二进制,但原生只支持UTF-8文本。
三、WebSocket:真正的“全双工”自由Ru果说HTTP是“寄信”,SSE是“听广播”,那WebSocket就是打
WebSocket是一个真正的独立协议。虽然它的握手阶段是借用了HTTP,但一旦握手成功,它就跟HTTP半毛钱关系没有了直接升级为WebSocket协议。 客户端会发一个特殊的HTTP请求,带上 Ru果服务器支持,就会返回一个 这一步完成后这条TCP连接上传输的就不再是HTTP文本了而是WebSocket的二进制帧格式。 WebSocket的数据传输格式非常严谨,它定义了帧的概念: 这Yi经和HTTP完全无关了是独立的二进制协议。这意味着它传输效率geng高,支持geng复杂的数据类型。 建立连接后客户端和服务端地位平等了。谁想说话就说话,不需要再等对方问。 这种模式特别适合聊天室、在线游戏、协同编辑这种双方互动频率极高的场景。 咱们把视角拉高,kankan这三者在传输层TCP眼里是个啥样。其实它们底层用的dou是同一条TCP连接,区别只在于上面跑的是什么格式的数据、谁Neng发、什么时候关。 一条TCP连接只活了0.4秒。用完即弃,简单粗暴。 一条TCP连接活了46秒。期间服务端不断往里写数据,客户端一直读。 一条TCP连接可Neng活几个小时。双方随时互发数据,这才是真正的“长连接”。 光说不练假把式,咱们来kankan代码里怎么用。这里以Spring Boot为例。 后端利用WebFlux的 前端直接用浏览器自带的 WebSocket稍微复杂一点,需要配置Handler: 前端使用 讲了这么多,Zui后还是得回到实际应用场景。别kan技术花里胡哨,选对工具才是关键。 我整理了一个简单的决策表,大家Ke以直接抄作业: HTTP 是“你问我答”,SSE 是“你问一次我一直答”,WebSocket 是“咱俩随便聊”。 三者底层dou是TCP连接,区别只在于谁Neng说话、说多久、什么时候挂。
事件频率低 → 轮询就够了简单可靠,别整复杂的。 事件频率高 → 必须 SSE,轮询Zuo不了WebSocket又太重。 需要双向通信 → WebSocket,这是它的主场,别用SSE硬凑。Upgrade: websocket的头,意思是:“大哥,咱们Neng不Neng换个协议聊?”GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket ← 请求升级协议
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZQ== ← 随机 key
Sec-WebSocket-Version: 13
101 Switching Protocols的状态码:HTTP/1.1 101 Switching Protocols ← 表示协议切换
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= ← 验证 key
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| |A| | |
|N|V|V|V| |S| | |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+-------------------------------+
| Masking-key | |
+-------------------------------+-------------------------------+
| Payload Data |
+---------------------------------------------------------------+
客户端 服务端
│ │
│── GET /chat │ ← HTTP 握手请求
│<── 101 Switching Protocols ─────│ ← 协议升级成功
│ │
│ ═══════ WebSocket 连接建立 ═══════│ ← 不再是 HTTP 了
│ │
│──── {"msg": "你好"} ──────────>│ ← 客户端发
│<─── {"msg": "你好!有什么Ke以帮你?"}│ ← 服务端发
│──── {"msg": "帮我写代码"} ─────>│ ← 客户端发
│<─── {"msg": "好的,请稍等"} ────│ ← 服务端发
│<─── {"msg": "代码写好了"} ──────│ ← 服务端主动发
│ │
│ ═══════ 任意一方关闭 ═════════════│
TCP 连接建立 → 发请求 → 收响应 → TCP 连接关闭
TCP 连接建立 → 发请求 → 收响应头 → 收数据块 → 收数据块 → ... → TCP 连接关闭
TCP 连接建立 → HTTP 握手 → 协议升级 → 双向帧传输 → ... → TCP 连接关闭
Flux流式特性,非常优雅:@GetMapping
public FluxEventSource
5.2 WebSocket 的后端与前端
// 前端
const es = new EventSource
es.onmessage = => {
const data = JSON.parse
// 每收到一条就处理,不需要等全部完成
appendToPage
}
es.addEventListener => {
es.close // 手动关闭
})
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers {
registry.addHandler, "/ws/chat");
}
@Bean
public WebSocketHandler chatHandler {
return new TextWebSocketHandler {
@Override
protected void handleTextMessage {
// 收到客户端消息
String payload = message.getPayload;
// 服务端Ke以随时主动发
session.sendMessage);
}
};
}
}
WebSocket API:
六、到底该怎么选?
// 前端
const ws = new WebSocket
ws.onopen = => {
ws.send // 客户端 → 服务端
}
ws.onmessage = => {
console.log // 服务端 → 客户端
}
ws.send // 随时Ke以发
一句话
维度
普通 HTTP
SSE
WebSocket
协议类型
HTTP/1.1
HTTP/1.1
ws://
通信方向
客户端 → 服务端
服务端 → 客户端
双向
连接生命周期
短
中长
长
数据格式
任意
纯文本
文本或二进制
浏览器 API
fetch / XMLHttpRequest
EventSource
WebSocket
服务端实现
@GetMapping
Flux + text/event-stream
WebSocketHandler + @EnableWebSocket
适用场景
查数据、提交表单
AI 流式输出、实时通知、构建状态推送
聊天室、游戏、协同编辑、双向交互
技术选型从来不是kan哪个技术Zui新、Zui酷,而是kan哪个Zui适合当下的业务场景。HTTP虽然老,但依然是互联网的基石;SSE虽然小众,但在AI时代迎来了第二春;WebSocket虽然强大,但维护成本也不低。
希望这篇文章Neng帮你彻底理清这三者的关系。下次再遇到“实时推送”的需求,别再傻傻地写setInterval轮询了也别上来就上WebSocket,先想想:我是不是只需要SSE就够了?
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback