想象你正在策划两档节目:一档是「AI 助手早间播报」广播电台,另一档是「多人连线热线」电话节目。 广播电台的工作方式很简单——主播(服务器)在直播间对着话筒不断输出,听众(客户端)只需要调准频道、安静收听。信息永远从电台单向流向听众,听众不需要说话。如果信号偶尔中断,智能收音机会自动重新搜索频道、接着播放,听众几乎无感知。 电话节目则完全不同——主持人、嘉宾、场外观众都能随时开口,每个人既在听也在说,这是一场真正的「双向对话」。但电话接通需要专门拨号、建立线路,断线了还得自己重拨,没人替你做。 SSE(Server-Sent Events,服务器发送事件)就是那台智能收音机——基于 HTTP 的服务器单向推送技术;WebSocket 就是那条电话线——基于 TCP 的全双工通信协议。今天这篇选型指南,就是帮你判断:你的 AI 服务到底该开一档广播,还是打一通电话?

岗位关联

掌握 SSE 与 WebSocket 的选型能力,是设计高吞吐流式 API 的核心技能,直接决定 AI 产品实时体验的架构路线上限。

目录
  1. 可视化演示
  2. 通信模式对比
  3. 协议底层机制
  4. 连接维护策略
  5. 数据格式差异
  6. 浏览器兼容性
  7. 典型应用场景
  8. 选型决策框架
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

直观对比SSE单向推送和WebSocket双向通信的架构差异,帮助AI服务架构师选择合适的流式API通信方案。

本节配有交互动效(进入视口后自动加载,约 3KB)。

SSE:单向流式推送 服务端→客户端单向推送,基于HTTP协议,实现简单 适合LLM流式输出、实时通知等单向数据场景 SSE是AI流式API的首选方案

通信模式对比

广播和电话最本质的区别,是听众的声音能不能传回直播间。你在开车时听电台,无论你怎么喊,主持人永远听不见;而打电话时,双方都能随时插话、相互回应。SSE 与 WebSocket 的第一个分水岭,恰恰就划在这条数据流方向上。

SSE 是一条单向管道,术语叫单工通信。服务器把 HTTP 响应体当作一条永不关闭的送水管道,消息从服务器端源源不断流出,浏览器用 EventSource 对象在另一端接水。这条管道上只有「服务器写、客户端读」一个方向,客户端若想反向发消息,只能另开一个普通的 HTTP 请求。

WebSocket 则是一条真正的全双工通道。连接建立之后,两端各自持有收发两用的消息帧接口,服务器和客户端可以同时发消息、互不排队、互不阻塞。聊天、白板、游戏操作这类「两边都频繁说话」的场景,只有全双工才自然。

选广播还是电话,先问自己:听众需不需要在收听时插话?如果你的 AI 产品只是「播音员」单向输出,广播天生更省力;只有需要实时对话时才值得拉起一条电话线。

SSE:Server→ push ClientWebSocket:Server⟺ msg  msg Client\text{SSE:}\quad \text{Server} \xrightarrow{\ \text{push}\ } \text{Client} \qquad\qquad \text{WebSocket:}\quad \text{Server} \underset{\ \text{msg}\ }{\overset{\ \text{msg}\ }{\Longleftrightarrow}} \text{Client}
箭头代表消息流动方向:SSE 只有一条指向客户端的单行箭头,WebSocket 有上下两条逆向箭头,表示双向同时通行。
  1. SSE 方向标记箭头永远从 Server 指向 Client,表示消息无法在连接上反向流动,客户端要回话必须另外发请求。
    Server→ push Client\text{Server} \xrightarrow{\ \text{push}\ } \text{Client}
  2. WebSocket 双向标记上下两条箭头同时存在,表示同一条连接内双向车道实时通行,任何一端都能随时发消息。
    Server⟺ msg  msg Client\text{Server} \underset{\ \text{msg}\ }{\overset{\ \text{msg}\ }{\Longleftrightarrow}} \text{Client}

协议底层机制

广播电台用的是国家统一规划的公共频段,听众手里的收音机不用做任何改装就能接收;而打电话必须从运营商那里专门拉一条线路,从交换机一路连通到对方家里。SSE 和 WebSocket 在协议层面也体现了同样的「复用」与「新建」之别。

SSE 跑在普通 HTTP 之上。客户端发一个 GET 请求,服务器不在响应体结束时断掉连接,而是持续向响应体里写入文本片段。由于它本质就是 HTTP,Nginx、CDN、负载均衡、防火墙这些基础设施天然认识它,几乎零改造就能穿透复杂网络。

WebSocket 则是独立的协议。客户端先发一个带上 Upgrade: websocket 头部的 HTTP GET 请求,服务器返回 101 Switching Protocols 状态码后,这条 TCP 连接才从 HTTP 切换到 WebSocket 帧协议。中间每一层代理都必须显式支持 Upgrade 跳板,否则连接会被拦在半路。

广播不用改造收音机频道,电话却需要从头到尾把线路打通。SSE 对 HTTP 基础设施的「亲和力」,在代理防火墙林立的企业级网络环境中,是常常被低估的隐形优势。

GET /chat HTTP/1.1 → Upgrade: websocket  HTTP 101 Switching Protocols\text{GET /chat HTTP/1.1} \ \xrightarrow{\ \text{Upgrade: websocket}\ } \ \text{HTTP 101 Switching Protocols}
握手是一次「换线仪式」:先用 HTTP 敲门,服务器同意后双方立刻切换成 WebSocket 方言交流。
  1. 握手请求客户端用普通 GET 请求发起,头部携带 Upgrade: websocket 声明「我想切换协议」。
    GET /chat HTTP/1.1 → Upgrade: websocket \text{GET /chat HTTP/1.1} \ \xrightarrow{\ \text{Upgrade: websocket}\ }
  2. 切换响应服务器返回 101 Switching Protocols,表示「同意换线」,此后连接按 WebSocket 帧格式通信。
    HTTP 101 Switching Protocols\text{HTTP 101 Switching Protocols}

连接维护策略

收音机一旦信号变差,会自动重新搜索频道、继续播放刚才的节目;而电话断线后,你必须自己记起电话号码、手动重拨。这两种「断线体验」的差异,恰好对应 SSE 与 WebSocket 在连接维护上的默认行为。

EventSource 天然内置断线重连机制。连接意外断开后,浏览器会自动重新发起 GET 请求,并且能携带 Last-Event-ID 响应头,告诉服务器「你刚才播到哪一条了,从这里继续补播」。AI 流式输出中断后自动续传,几乎零代码白拿。

WebSocket 则没有任何自动重连能力。断线后浏览器只触发一个 close 事件,重试间隔怎么定、上次消息从哪条继续、要不要缓存未发消息,全部需要你自己实现。这些「隐藏工程量」在方案评审时经常被忽略,上线后才发现要写一整套连接管理器。

SSE 自带「搜台续播」的省心能力,对 AI 流式输出这种单次连接可能持续数十秒甚至数分钟的场景尤其宝贵。WebSocket 虽然强大,但断线重连这笔账,迟早要还。

tn=min⁡(t0×2n, tmax⁡)t_n=\min\big(t_0\times 2^{n},\ t_{\max}\big)
指数退避是重连的「温柔策略」:越失败就等得越久,既不会死循环轰炸服务器,也能在网络恢复后及时续上。
  1. 重试次数n 是第几次重连尝试,t0 是初始等待时间。
    t0×2nt_0\times 2^{n}
  2. 指数增长重试次数越多,等待时间按 2 的幂次增长,避免重连风暴。
    tn=min⁡(t0×2n, tmax⁡)t_n = \min(t_0 \times 2^{n},\ t_{\max})
  3. 封顶保护等待时间超过 tmax 后不再增长,保证连接恢复后能及时重连。
    min⁡(⋅, tmax⁡)\min(\cdot,\ t_{\max})

数据格式差异

广播字幕是一行一行往下滚的文字,格式固定、谁都能读;电话则既能说人话,也能传入传真、图片、音频等各种文件。SSE 与 WebSocket 在「讲什么语言、能传什么货」上也分道扬镳。

SSE 只能传输 UTF-8 文本。每条事件以 data: 开头、以空行 \n\n 结尾,中间可以用 event: 指定事件名、用 id: 指定消息序号。因为它是纯文本流,任何 HTTP 代理、日志系统、抓包工具都能直接读懂内容,排查问题非常直观。若要传二进制数据,只能 base64 编码,体积膨胀约 33%。

WebSocket 支持文本帧和二进制帧两种消息类型。通信双方可以直接交换 ArrayBuffer、Blob 等二进制数据,不需要任何编码转换。对音频 PCM 帧、图像块、游戏状态快照这类数据,WebSocket 的原生二进制能力省下了大量编码开销。

广播只放送文字,电话能传文件。如果你的 AI 流式返回只是 JSON 文本片段,SSE 足够且更直观;如果要推音频流或图像块,WebSocket 的二进制帧才是主场。

SSE stream:event: chat⏟事件类型data: token="你"⏟消息内容空白行⏟事件分隔符\text{SSE stream:}\quad \underbrace{\texttt{event: chat}}_{\text{事件类型}} \quad \underbrace{\texttt{data: token="你"}}_{\text{消息内容}} \quad \underbrace{\text{空白行}}_{\text{事件分隔符}}
一条 SSE 事件由「类型行 + 数据行 + 空行」三段组成,浏览器按空行切分出一个个独立事件。
  1. 类型行event 字段标注本条事件类型,对应浏览器分发的自定义事件名。
    event: chat\texttt{event: chat}
  2. 数据行data 字段携带实际内容,多条 data: 行会按顺序合并成一条消息。
    data: token="你"\texttt{data: token="你"}
  3. 分隔符连续两个换行代表一条事件结束,浏览器据此切分事件流。
    空白行\text{空白行}

浏览器兼容性

收音机几乎是家家户户的标配;电话早年在大山深处信号不佳,但随着基站铺开,覆盖率已经很高。SSE 与 WebSocket 在浏览器端的支持度,也呈现出「略逊但够用」与「全面覆盖」的微妙差距。

EventSource 的兼容性「差一点但不是大问题」:IE 全家和旧版 Edge 不支持,其余主流浏览器(Chrome、Firefox、Safari、新版 Edge)全部原生支持。如果产品必须兼容 IE 时代的老旧终端,官方有成熟的 polyfill 方案可以补上能力。

WebSocket 则几乎所有浏览器都原生支持,包括早期移动端浏览器。作为实时 Web 的底层基建协议,它的覆盖范围接近全网。但注意,「支持连接」不等于「支持稳定连接」——公司内网代理可能拦截 Upgrade 请求,这在兼容性评估中经常被忽略。

收音机基本每家都有,电话也几乎全覆盖。兼容性这一维度,两边都够用,不构成决定性差异——除非你的用户群体偏偏集中在老旧浏览器上。

PSSE≈95%,PWebSocket≈97%P_{\text{SSE}} \approx 95\%,\qquad P_{\text{WebSocket}} \approx 97\%
浏览器支持率差了约两三个百分点,通常可以用 polyfill 填平,很少成为选型的一票否决项。
  1. SSE 支持率约 95% 的浏览器环境原生支持 EventSource,缺口集中在 IE 与旧版 Edge。
    PSSE≈95%P_{\text{SSE}} \approx 95\%
  2. WebSocket 支持率约 97% 的环境原生支持,覆盖更早更广。
    PWebSocket≈97%P_{\text{WebSocket}} \approx 97\%
  3. 差距本质几个百分点的差异可通过 polyfill 弥合,真正的卡点往往是企业代理而非浏览器。
    PSSE≈PWebSocketP_{\text{SSE}} \approx P_{\text{WebSocket}}

典型应用场景

什么时候开广播,什么时候打电话?生活经验早就给了答案:路况播报、天气预警、新闻联播——单向通知用广播;热线聊天、多人会议、远程协作——互动沟通用电话。AI 服务的场景选择,遵循同样的逻辑。

SSE 的主场是「高频单向通知 + 长耗时流式输出」。大模型 token 逐个滚出的打字机效果、Agent 执行日志的流式上报、股票行情推送、新闻瀑布流,这些场景中 90% 以上的消息都从服务器流向客户端。SSE 用一个 HTTP 连接 + 自动重连就全部搞定,连接数省、代码量省、运维负担也轻。

WebSocket 的主场是「低延迟双向交互」。即时聊天、多人白板、云游戏、实时协同编辑、IoT 设备控制,客户端要频繁发指令,服务器要实时回推状态。这时只有双向车道能承载「你一句我一句」的密集对话,SSE 的「另开 POST 请求」模式会显得笨重且延迟更高。

AI 聊天机器人的「打字机字幕」是典型广播场景;但如果你做的是「AI 协同画布」,服务器和用户都要实时改动图形,就得拿起电话。先区分场景,再谈选型。

f(s)={SSE,消息 90% 从 Server 到 ClientWebSocket,双向高频且需要低延迟f(s)=\begin{cases}\text{SSE}, & \text{消息 90\% 从 Server 到 Client}\\\text{WebSocket}, & \text{双向高频且需要低延迟}\end{cases}
场景匹配函数:先判断数据流向的倾向性,再决定拿起收音机还是话筒。
  1. 单向主导分支绝大多数数据由服务器喷出,SSE 的连接成本与实现复杂度最低。
    SSE,消息 90% 从 Server 到 Client\text{SSE}, \quad \text{消息 90\% 从 Server 到 Client}
  2. 双向主导分支客户端也频繁发送,必须升级到 WebSocket 双向通道。
    WebSocket,双向高频且需要低延迟\text{WebSocket}, \quad \text{双向高频且需要低延迟}

选型决策框架

到了拍板环节,就像给家里选购通信套餐:把需求一条条列出来,对着清单打勾,而不是听销售吹得天花乱坠。SSE 与 WebSocket 的选型也可以固化为四个步骤的决策框架。

第一步看数据流向:消息 90% 单向流动,直接选 SSE;双向高频交互,选 WebSocket。第二步看消息形态:纯 JSON 文本流,SSE 够用;需要传输二进制音频、图像、自定义帧,WebSocket 更顺手。第三步看连接规模:广播场景动辄上万并发连接,WebSocket 长连接吃内存、占文件描述符更多,架构复杂度更高;SSE 借助 HTTP/2 还能多路复用。第四步看基础设施:SSE 是 HTTP,代理和防火墙天然放行;WebSocket 要求全链路代理支持 Upgrade,改造周期不可低估。

把四个维度量化,可以得到一个加权评分模型:

其中 $b$ 为双向需求度(0-1),$f$ 为二进制需求度(0-1),$c$ 为基建复杂度成本(0-1),$w_1,w_2,w_3$ 为对应权重。

没有最好的通信协议,只有最适配的对话方式。绝大多数 AI 流式 API 用广播(SSE)就已超额完成任务,省下的复杂度就是团队最宝贵的时间。

scoreWS=w1×b+w2×f−w3×c\text{score}_{WS}=w_1\times b+w_2\times f-w_3\times c
这个分数代表「选 WebSocket 的净收益」:双向和二进制需求越高越加分,基建改造越复杂越扣分,分数显著高于 1 才值得选它。
  1. 双向需求分b 越大越是聊天协作类场景,WebSocket 加分越多。
    w1×bw_1\times b
  2. 二进制需求分f 高说明要传音频视频,WebSocket 原生优势转化为分数。
    w2×fw_2\times f
  3. 复杂度扣分c 来自代理改造、重连自研、运维成本,从总分中扣除。
    −w3×c-w_3\times c
  4. 决策比较SSE 可视为基准分 1,WebSocket 只有当净收益显著大于 1 时才值得切换。
    scoreWS≫1\text{score}_{WS} \gg 1

AI 应用场景

大模型流式对话接口(SSE 广播台)

阶段:LLM 推理输出与在线服务部署

解决的问题:传统方式等模型全部推理完再一次性返回,用户看到首个字往往要等好几秒,体验笨重。AI 方式下,SSE 让服务器把 token 逐个「播报」给客户端,首 token 延迟降低到几百毫秒,配合打字机渲染,对话体验丝滑自然。

具体案例:某 AI 客服产品将后端对话接口改为 text/event-stream,用户在提问后约 0.3 秒就看到第一个字开始滚动,整体感知速度提升了近 5 倍。断网时浏览器自动重连并携带 Last-Event-ID,漏掉的回复片段由服务端补发。

多人在线协同白板(WebSocket 电话线)

阶段:实时协同编辑与状态同步

解决的问题:AI 设计助手与多名人类设计师共享一块画布,每个人拖拽图形、修改标注,动作都要实时同步给所有人。SSE 的单向管道无法承载客户端高频的图形指令,WebSocket 的双向通道让每次拖动都像电话里的即时对话。

具体案例:某 AI 设计工具团队用 WebSocket 实现画布状态同步,服务端维护房间连接池,将 AI 生成的设计草图和用户的手动调整都以二进制帧广播,多人协同时延稳定在 50ms 以内。

金融行情推送平台(SSE 播报员)

阶段:行情数据管道与推送服务

解决的问题:股票行情天然是「交易所 → 平台 → 用户」的单向瀑布流,客户端不需要向服务器发任何行情数据。用 WebSocket 纯属大材小用,还带来连接维护和重连自研的额外成本。SSE 以近乎零成本的方式实现每秒多档行情推送。

具体案例:某量化行情平台用 SSE 向数千客户端推送沪深 Level-1 行情,服务端只需维护简单的 HTTP 连接池,配合 Kafka 消费行情后直接写入响应流,单机支撑 5 万并发连接,故障时自动重连自动续推。

Python 演示

python61 行
"""Compare SSE and WebSocket for streaming AI responses."""import jsonimport timefrom http.server import BaseHTTPRequestHandler, HTTPServerfrom urllib.parse import urlparse  def token_generator(text):    """Yield each character of text with a small delay."""    for char in text:        yield char        time.sleep(0.05)  class SSEHandler(BaseHTTPRequestHandler):    """Demo server: SSE streaming plus a simple client-to-server POST."""     def do_GET(self):        if urlparse(self.path).path != "/stream":            self.send_response(404)            self.end_headers()            return        self.send_response(200)        self.send_header("Content-Type", "text/event-stream")        self.send_header("Cache-Control", "no-cache")        self.send_header("Connection", "keep-alive")        self.end_headers()        reply = "Hello from AI streaming server!"        for token in token_generator(reply):            payload = "data: " + json.dumps({"token": token}) + "\n\n"            self.wfile.write(payload.encode("utf-8"))            self.wfile.flush()     def do_POST(self):        if urlparse(self.path).path != "/chat":            self.send_response(404)            self.end_headers()            return        length = int(self.headers.get("Content-Length", 0))        body = json.loads(self.rfile.read(length) or b"{}")        self.send_response(200)        self.send_header("Content-Type", "application/json")        self.end_headers()        echo = {"echo": body.get("message", "")}        self.wfile.write(json.dumps(echo).encode("utf-8"))     def log_message(self, fmt, *args):        print("[server] " + (fmt % args))  def main():    server = HTTPServer(("localhost", 8765), SSEHandler)    print("SSE server running at http://localhost:8765/stream")    try:        server.serve_forever()    except KeyboardInterrupt:        server.shutdown()  if __name__ == "__main__":    main()
目的:用纯标准库实现一个 SSE 流式推送服务器,模拟 AI 模型逐 token 输出,同时提供 POST 接口让客户端发消息,展示 SSE 的「单向广播 + 另开请求发消息」典型架构。
  1. self.send_header("Content-Type", "text/event-stream")设置响应类型为事件流,浏览器收到后才知道这是 SSE 长连接。
  2. self.send_header("Cache-Control", "no-cache")禁止代理和浏览器缓存流式内容,保证每条消息实时到达。
  3. self.end_headers()结束响应头并保持连接不断开,后续写入的内容都作为响应体持续输出。
  4. payload = "data: " + json.dumps({"token": token}) + "\n\n"按 SSE 协议拼装数据帧,data 前缀加空行结尾,浏览器自动解析。
  5. self.wfile.flush()立即刷新缓冲区,让 token 以毫秒级延迟到达客户端,而不是攒一批再发。
  6. def do_GET(self)GET 请求建立 SSE 流;客户端发消息则走 do_POST,两个通道各自独立,正是「广播 + 另发信件」的组合。

常见误区

误区很多人一看到「服务器发送事件」这个名词,就断定 SSE 是单向的,客户端想发消息给 AI 只能换 WebSocket。实际上我在面试中也常遇到候选人大谈 WebSocket 的必要性,却不知道 SSE 早已支撑起无数对话产品。

正解SSE 指的是「服务器 → 客户端」这条长连接方向是单向的,但客户端完全可以通过额外的普通 HTTP POST 请求把消息发给服务器(也就是上一节 Python 演示里 do_POST 的角色)。服务端收到消息后,在原来的 SSE 流里把 AI 回复推回去。对话系统用「POST 进、SSE 出」的架构,正是目前大模型应用的主流方案。

为何常见:因为「单向」这个定语太容易被理解为「整个系统只能有一个方向」,而忽略了 HTTP 请求-响应模型里客户端天然的发送能力。

误区不少开发者默认 WebSocket 和 SSE 一样,断开后浏览器会自动重连,所以选型时觉得 WebSocket 更强大又免维护,一头扎进去。

正解恰恰相反。SSE 的 EventSource 从设计之初就内置了断线重连和 Last-Event-ID 续传机制,而 WebSocket 在断线后只抛一个 close 事件,重连间隔、退避策略、消息补偿全部要开发者自己实现。选 WebSocket 意味着你要额外维护一套连接状态机,这是最常见的隐性成本。

为何常见:人们容易把「连接稳定」想成协议层的默认职责,但这个世界上没有免费的自动重连——SSE 把重连做进了标准,而 WebSocket 把选择权留给了你。

误区看到 SSE 只支持 UTF-8 文本,就认为它无法胜任现代多媒体场景,觉得凡是涉及二进制就必须上 WebSocket。

正解SSE 确实不原生支持二进制帧,但可以通过 base64 编码把任何二进制数据塞进 data 字段,通用性完全够。虽然体积膨胀约 33%,对带宽敏感的场景确实吃亏,但大量 AI 流式场景传的是 JSON 片段,根本涉及不到二进制。而 WebSocket 的二进制优势真正发挥作用的是音频流、图像块等高频大体积场景。

为何常见:人们容易从「不支持」直接跳到「不能用」,而忽略了 base64 这个无处不在的编码桥梁,也忽略了大多数业务其实根本不需要二进制。

误区潜意识里觉得 WebSocket 是「专用长连接」,SSE 是「普通 HTTP」,专用的一定更快,于是性能敏感场景无脑选 WebSocket。

正解在单条连接的端到端延迟上,两者并没有数量级差异。SSE 基于 HTTP/2 时还能多路复用,一条 TCP 连接承载多个推送流;而且 SSE 省去了握手的额外开销,首包到达时间往往更快。真正影响性能的是消息频率、序列化开销和服务端架构,而不是协议本身。WebSocket 的「快」更多体现在双向帧交换的灵活性上,并非绝对吞吐优势。

为何常见:人们习惯用「协议新旧」来判断性能强弱,但网络性能的瓶颈通常在于业务逻辑和系统架构,协议选型只是其中一个变量。

面试题

Q1. SSE 的全称是什么?

单选题 · easy

  • A.Server-Sent Events← 正确答案
  • B.Simple Stream Engine
  • C.Socket Event Exchange
  • D.Server-Side Encryption

答案:A。SSE 即 Server-Sent Events(服务器发送事件),是浏览器原生支持的服务端推送技术。B、C 是杜撰的组合词,D 是服务端加密的缩写混淆项。记住「服务器主动发送事件给客户端」这个语义就能锁定答案。

Q2. SSE 连接依赖于哪种底层协议?

单选题 · easy

  • A.HTTP 长连接← 正确答案
  • B.UDP 通信协议
  • C.TCP 三次握手
  • D.TLS 独立协商

答案:A。SSE 基于 HTTP 长连接实现,服务器在 HTTP 响应体中持续写入数据。UDP 是面向数据报的协议,TCP 三次握手只是建立连接的底层过程,TLS 独立协商则不是专门针对 SSE 的机制。

Q3. SSE 消息流中,数据行以哪个前缀开头?

单选题 · mid

  • A.data:← 正确答案
  • B.msg:
  • C.text:
  • D.info:

答案:A。SSE 标准规定每条数据必须以 data: 前缀开头,浏览器通过该前缀识别消息内容。msg:、text:、info: 都不是 SSE 协议的合法字段前缀,把帧格式记牢就能答对。

Q4. WebSocket 通过什么机制从 HTTP 升级为 WebSocket 协议?

单选题 · mid

  • A.HTTP Upgrade 请求头← 正确答案
  • B.TCP 端口重复绑定
  • C.建立独立 UDP 通道
  • D.DNS 协议重新协商

答案:A。WebSocket 握手依赖 HTTP 的 Upgrade: websocket 请求头,服务器返回 101 状态码后完成协议切换。B、C、D 都是捏造的升级方式;这是一道考查「先 HTTP 敲门、再切换协议」流程的标准题。

Q5. SSE 相比 WebSocket 的独特优势是哪个?

单选题 · mid

  • A.浏览器内置自动重连← 正确答案
  • B.支持二进制数据帧
  • C.无需 HTTP 协议
  • D.天然支持双向通信

答案:A。EventSource 内置断线自动重连和 Last-Event-ID 续传,这是 SSE 的招牌能力。二进制帧和双向通信恰恰是 WebSocket 的优势,SSE 必须基于 HTTP 才能工作,所以 C 也不对。

Q6. EventSource 要监听服务器发送的自定义事件,应该怎么做?

单选题 · hard

  • A.使用 addEventListener 注册← 正确答案
  • B.覆盖默认 onmessage 属性
  • C.新建一个 custom 回调函数
  • D.设置 HTML 事件标签属性

答案:A。服务器通过 event: customName 指定自定义事件名时,客户端必须用 addEventListener('customName', handler) 才能捕获。onmessage 只能处理默认 message 事件,C、D 是无效写法。这会区分「只背 API 名字」和「真正用过 EventSource」的候选人。

Q7. WebSocket 对象发送文本消息调用的方法是什么?

单选题 · easy

  • A.send()← 正确答案
  • B.write()
  • C.post()
  • D.push()

答案:A。WebSocket 实例通过 send(data) 方法发送消息,文本、ArrayBuffer、Blob 都走这个入口。write 是 Node 流的方法,post 是 HTTP 动词,push 是服务端推送相关概念,都不是 WebSocket API。

Q8. 下列场景中,更适合选择 SSE 的有哪些?

多选题 · mid

  • A.AI 对话内容流式输出← 正确答案
  • B.新闻资讯实时推送← 正确答案
  • C.对战游戏操作同步
  • D.在线白板多人协作

答案:AB。AI 流式输出和新闻推送都是「服务器单向喷数据」,SSE 连接轻量、自动重连,是理想选择。对战游戏操作同步和在线白板要求客户端频繁发指令、服务器实时回推,属于双向高频交互,必须用 WebSocket。

Q9. 相比 SSE,WebSocket 的技术优势包括哪些?

多选题 · hard

  • A.真正的全双工对话← 正确答案
  • B.原生支持二进制帧← 正确答案
  • C.默认自动重连恢复
  • D.内置消息持久化

答案:AB。WebSocket 是全双工协议且原生支持二进制帧,这是它相对 SSE 的两大核心优势。自动重连恰恰是 SSE 的特性而非 WebSocket 的内置能力,消息持久化两种协议都不提供,需要业务层自己实现。

Q10. 关于 SSE 与 WebSocket 的选型判断,正确的有哪些?

多选题 · extreme

  • A.SSE 可复用 HTTP 基础设施← 正确答案
  • B.WebSocket 需自行实现重连← 正确答案
  • C.SSE 适合高频单向推送← 正确答案
  • D.WebSocket 仅支持文本数据

答案:ABC。SSE 跑在 HTTP 之上,可以穿透绝大多数代理和防火墙,基础设施复用成本低;WebSocket 断线后必须自己实现重连;高频单向推送正是 SSE 的主场。D 明显错误,WebSocket 支持文本和二进制两种帧。综合题考查的是对两种协议全貌的把握。