当前位置: 首页 > ai >正文

【简单易懂】SSE 和 WebSocket(Java版)

一、前言

  • SSE(Server-Sent Events) 和 WebSocket 是两种用于实现实时通信的 Web 技术;
  • 但它们在设计、用途和实现方式上有显著区别。

二、SSE(Server-Sent Events)

  • 定义基于 HTTP 的单向通信协议,允许服务器主动向客户端推送数据

  • 特点

    • 单向通信:仅支持服务器 → 客户端的单向数据推送。
    • 基于 HTTP:使用简单,无需额外协议,兼容现有 HTTP 基础设施。
    • 自动重连:内置断线重连机制,客户端会自动尝试重新连接。
    • 轻量级:数据格式为纯文本(如 text/event-stream),适合推送简单数据,如新闻、股价。
  • 适用场景

    • 实时通知(如新闻、天气更新)。
    • 服务器主导的实时数据推送(如日志流、进度条更新)。
  • 局限性

    • 不支持客户端向服务器发送消息。
    • 部分旧浏览器(如 IE)不支持。

三、WebSocket

  • 定义基于 TCP 的全双工通信协议,支持客户端与服务器双向实时通信
  • 特点
    • 双向通信:客户端和服务端可以同时发送和接收数据。
    • 独立协议:通过 HTTP 升级握手建立连接(ws:// 或 wss://),之后脱离 HTTP 独立运行。
    • 低延迟:持久化连接,适合高频交互场景(如聊天、游戏)。
    • 支持二进制数据:可传输文本或二进制数据(如图片、音频)。
  • 适用场景
    • 实时聊天、协作工具。
    • 多人在线游戏、实时交易系统。
  • 局限性
    • 实现复杂度较高(需处理连接状态、心跳检测等)。
    • 需要服务器和客户端同时支持 WebSocket 协议。

四、核心区别对比

在这里插入图片描述


五、代码示例(基于Java的Spring Boot)

1、SSE

A.服务端代码
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;@RestController
public class SseController {@GetMapping(path = "/sse-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public SseEmitter streamEvents() {SseEmitter emitter = new SseEmitter(60_000L); // 超时时间 60 秒// 模拟实时数据推送(实际可能从数据库或外部服务获取)new Thread(() -> {try {for (int i = 0; i < 10; i++) {SseEmitter.SseEventBuilder event = SseEmitter.event().data("SSE 数据 - " + i) // 推送的数据.id(String.valueOf(i))   // 事件 ID(可选).name("sse-event");      // 事件名称(可选)emitter.send(event);Thread.sleep(1000); // 间隔 1 秒}emitter.complete(); // 完成推送} catch (Exception e) {emitter.completeWithError(e); // 异常处理}}).start();return emitter;}
}
B.客户端代码(JavaScript)
const eventSource = new EventSource('/sse-stream');
eventSource.onmessage = (e) => {console.log("收到 SSE 数据:", e.data);
};
eventSource.onerror = (e) => {console.error("SSE 连接错误:", e);
};
C.关键点
  • 服务端使用 SseEmitter 发送事件流。

  • 客户端通过 EventSource 监听数据。

2、WebSocket

A. [服务端]依赖引入(pom.xml)
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
B. [服务端]WebSocket配置类
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new MyWebSocketHandler(), "/ws").setAllowedOrigins("*"); // 允许跨域}
}
C. [服务端]WebSocket处理器
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;public class MyWebSocketHandler extends TextWebSocketHandler {@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {// 连接建立时触发session.sendMessage(new TextMessage("服务端:连接成功!"));}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// 收到客户端消息时触发String clientMsg = message.getPayload();System.out.println("收到客户端消息: " + clientMsg);// 回复客户端session.sendMessage(new TextMessage("服务端回复: " + clientMsg));}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) {// 连接关闭时触发System.out.println("WebSocket 连接关闭");}
}
D. 客户端测试(JavaScript)
const socket = new WebSocket('ws://localhost:8080/ws');// 连接成功
socket.onopen = () => {console.log("WebSocket 连接已建立");socket.send("Hello WebSocket!");
};// 接收消息
socket.onmessage = (e) => {console.log("收到消息:", e.data);
};// 连接关闭
socket.onclose = () => {console.log("WebSocket 连接已关闭");
};
E.关键点
  • 服务端通过 WebSocketHandler 处理连接和消息
  • 客户端使用浏览器原生 WebSocket API 通信

六、使用建议 / 如何选择

  • 选择 SSE
    • 只需服务器向客户端推送数据(如实时通知、数据监控)。
    • 希望快速实现且兼容现有 HTTP 服务。
  • 选择 WebSocket
    • 需要双向实时交互(如聊天室、在线游戏)。
    • 对延迟敏感或需传输二进制数据。

七、总结

  • SSE 适合单向服务器推送场景,简单且对开发友好
  • WebSocket 适合双向高频通信,性能更优但实现复杂
  • 两者可结合使用(例如:用 SSE 接收通知,用 WebSocket 处理交互)。
  • 根据实际需求选择技术方案。
http://www.xdnf.cn/news/5785.html

相关文章:

  • 删除购物车中一个商品
  • Unity
  • KMDA-6920成功助力印度智慧钢厂SCADA系统,打造高效可靠的生产监控平台
  • 菜狗的脚步学习
  • 【android bluetooth 框架分析 02】【Module详解 7】【VendorSpecificEventManager 模块介绍】
  • 前端开发避坑指南:React 代理配置常见问题与解决方案
  • BFS算法篇——打开智慧之门,BFS算法在拓扑排序中的诗意探索(上)
  • 机器学习——聚类算法练习题
  • [Java实战]Spring Boot 3构建 RESTful 风格服务(二十)
  • java使用 FreeMarker 模板生成包含图片的 `.doc` 文件
  • RustDesk:开源电脑远程控制软件
  • 端侧智能重构智能监控新路径 | 2025 高通边缘智能创新应用大赛第三场公开课来袭!
  • 霍夫圆变换全面解析(OpenCV)
  • 6. 多列布局/用户界面 - 杂志风格文章布局
  • 手机换IP真的有用吗?可以干什么?
  • spark-local模式
  • WM_TIMER定时器消息优先级低,可能会被系统丢弃,导致定时任务无法正常执行
  • T-BOX硬件方案深度解析:STM32与SD NAND Flash存储的完美搭配
  • Linux中find命令用法核心要点提炼
  • spark-standalone
  • http断点续传
  • Games101作业四
  • 在Ubuntu服务器上部署Label Studio
  • 从SAM看交互式分割与可提示分割的区别与联系:Interactive Segmentation Promptable Segmentation
  • Java基础(IO)
  • Android Native 之 自定义进程
  • 【氮化镓】电子辐照下温度对GaN位移阈能的影响
  • 开源网络地图可视化第五章学习指南
  • 【认知思维】光环效应:第一印象的持久力量
  • MySQL 8.0 OCP 1Z0-908 题目解析(2)