一个 jar 搞定实时推送:我的轻量级 SSE 中间件 Stream Nexus

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

由于最近一直再做服务端推送相关的业务,但是想要自己从0到1的搭建,考虑的东西确实不少,之前也介绍过SpringBoot集成SSE的文章。通过这几天的整理,将项目托管到GitHub上,方便后面参考或者直接使用。本节就介绍一下这个小项目。

02 项目介绍

项目没有引入除了spring-boot-starter-webmvc没有在引入其他三方依赖。将Stream Nexus项目做成一个可以独立部署的项目,部署之后直接使用即可,无需在考虑断线重连、无效客户端导致内存溢出等问题。此外,还增加客户端的管理系统,可以试试看到在线的客户端信息。

GitHub地址:github.com/simonking-w...

本项目目前只接入了SSE,后面有空了还会接入websocket。主要你的项目目录:

text 复制代码
stream-nexus
├── pom.xml           # 父 POM(Spring Boot 4.1.1,Java 17)
├── .dockerignore     # 构建上下文瘦身(必须留在上下文根 = 仓库根)
├── docs/             # 设计文档
├── nexus-common/     # 跨模块契约
└── nexus-sse/        # SSE推送服务实现(端口 8088)
└── nexus-websocket/  # websocket推送服务实现【待实现】
    

2.1 主要功能

  • 长连接订阅:GET /sse/subscribe,连接永不过期,一条连接可同时订阅多个业务模块;modules 留空默认订阅 global
  • 双寻址推送:按 bizModule 广播、按 clientId 定向,两者可同时使用(命中并集、按连接去重)
  • 全局模块 global:订阅侧默认值;推 global = 广播给全部在线连接,推其它模块时订阅 global 的连接同样会收到(纯定向推送不扩散)
  • 全局跨域:WebMvcConfigurer#addCorsMappings 注册 /**,源 / 方法 / 头 / 凭证全量放行,无需配置
  • 心跳保活:服务端每 15s 下发 PING,客户端回 PONG,同时压制 LB / NAT 空闲断链
  • 死连接回收:四条判据(回调 / 心跳超时 / 软重置 / 写入失败)统一回收,避免半开连接堆积
  • 推送鉴权:X-Sse-AppId + X-Sse-Key 配对校验(常量时间比对),并按应用限制可推送的模块白名单
  • 运维接口:在线连接查询与强制下线(connections);推送应用 appId/key 的运行时增删(apps)
  • 内置页面:Thymeleaf:/ 直达 /admin(默认:连接台账 + 一键下线 + 应用管理),/console 推送测试页(应用下拉、内容自定义、默认模块 test)

2.2 设计优势

  • 零中间件 : 连接表与消息 ID 全在内存,不需要 Redis / MQ,单机 java -jar 即可跑,接入成本极低。
  • 永不过期 + 主动探测 :SseEmitter(0L) 让容器不再替你超时,配合 PING/PONG 一问一答解决 TCP 半开连接(进程被杀、笔记本合盖、NAT 静默丢表)下 send() 仍返回成功、死连接几小时都发现不了的难题。
  • 统一回收入口 :所有回收路径只走 SseClientRegistry.remove(),保证连接主表与模块倒排索引一致,杜绝索引泄漏与内存缓慢增长。
  • 极简消息体 :SseMessage 固定 6 个字段。协议层字段用枚举保证稳定,业务层字段(bizModule / action)用字符串,业务方新增维度无需改公共包、无需改枚举。
  • 契约与实现分离 :nexus-common 只放契约(消息体、枚举、常量、推送入参出参),业务系统可单独依赖它,不必引入服务端实现。
  • 精细的推送鉴权 :X-Sse-AppId 定位应用、X-Sse-Key 证明身份,二者必须配对;每个应用可配 allowed-modules 白名单,越权推其他模块返回 403。
  • 连接复用 :一条 SSE 连接可订阅多个 bizModule,规避浏览器同域 HTTP/1.1 的 6 连接上限。

2.3 环境要求

  • JDK 17+
  • Maven 3.8+(或直接使用仓库自带的 mvnw / mvnw.cmd)

03 部署

部署方式提供了古老的java -jar xxx.jar的方式,需要编译打包。

还提供了Docker部署,也需要自行构建。

04 项目效果

由于项目在我本地,我就直接启动了。默认端口8088。

访问地址:http://localhost:8088

4.1 首页

首页有一个简单的仪表盘,同来统计连接数,以及活跃的连接数列表

4.2 推送应用

这里是为了推荐鉴权使用的,因为推送是通过REST直接访问的,通过鉴权防止恶意的数据推送,还可以指定秘钥推送的范围。

4.3 推送测试

这里连接地址可以修改,也可以用来测试其他SSE的连接。

直接建立连接、通过设置业务模块、动作甚至定向的摩西消息的推送。

4.3 效果

模拟3个连接:

新增应用的鉴权:

测试推送:

05 小结

Stream Nexus 中的nexus-sse 是一个极简的 SSE 实时推送中间件 ,定位是"业务系统通过 HTTP 灌消息,浏览器用 EventSource 收消息"的桥梁。

适合中小规模实时推送场景,毕竟收同源策略的影响,同源支持6个链接。后面还会集成nexus-websocket,争取做到部署即用,无需额外开发,方便开发者使用。感兴趣的老铁可以了解一下,提提意见!

相关推荐
vipxieliang1 小时前
ValidX 多租户系统的数据验证方案
java·spring boot
国奉1 小时前
iOS 音频格式转换怎么实现?从 AVAudioFile、AAC、MP3 到 FLAC 与批量转码架构
前端·后端
旺仔不是程序员1 小时前
索引膨胀与重建:PostgreSQL REINDEX 生产实践
数据库·后端·sql
AllFiles1 小时前
K8s Node Exporter 异常 Write 超时排查实录
运维·后端·kubernetes
Thneonl1 小时前
etcd 不只是数据库:K8s 控制面的命脉
后端·kubernetes
the局外人1 小时前
轻松掌握 LangGraph 的状态与节点
后端·langchain·llm
IT_陈寒1 小时前
Vite的静态资源引用把我坑惨了
前端·人工智能·后端
mldong1 小时前
13 套工作流后端共用一个 App 检查更新接口:0 张表,一行 SQL 没写
后端·架构
杨杨杨大侠1 小时前
聊几句就能让 AI 写代码,Spec 还有必要吗?
java·openai·ai编程