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

SpringBoot + WebSocket 实现实时消息推送(在线聊天/通知)

WebSocket 是实现服务端主动推送消息的常用技术,适用于在线聊天、系统通知、实时数据展示等场景。本文从零搭建一个 SpringBoot + WebSocket 的实时消息推送系统。

一、WebSocket 是什么

传统 HTTP 通信只能由客户端发起请求,服务端被动响应。WebSocket 建立连接后,服务端可以主动向客户端推送消息

对比HTTPWebSocket
通信方向客户端→服务端双向通信
连接方式每次请求新建连接建立连接后保持
实时性需要轮询即时推送
适用场景普通 API聊天、通知、实时数据

二、SpringBoot 整合 WebSocket

1. 引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

2. 配置 WebSocket

@ConfigurationpublicclassWebSocketConfig{@BeanpublicServerEndpointExporterserverEndpointExporter(){returnnewServerEndpointExporter();}}

三、核心:WebSocket 服务端

@Component@ServerEndpoint("/ws/{userId}")@Slf4jpublicclassWebSocketServer{/** 存放每个用户的 WebSocket 连接 */privatestaticMap<String,Session>sessionMap=newConcurrentHashMap<>();/** * 连接建立成功 */@OnOpenpublicvoidonOpen(Sessionsession,@PathParam("userId")StringuserId){sessionMap.put(userId,session);log.info("用户 {} 已连接,当前在线人数: {}",userId,sessionMap.size());}/** * 连接关闭 */@OnClosepublicvoidonClose(@PathParam("userId")StringuserId){sessionMap.remove(userId);log.info("用户 {} 已断开,当前在线人数: {}",userId,sessionMap.size());}/** * 收到客户端消息 */@OnMessagepublicvoidonMessage(Stringmessage,@PathParam("userId")StringuserId){log.info("收到用户 {} 的消息: {}",userId,message);}/** * 发生错误 */@OnErrorpublicvoidonError(Sessionsession,Throwableerror){log.error("WebSocket 错误",error);}/** * 向指定用户推送消息 */publicstaticvoidsendToUser(StringuserId,Stringmessage){Sessionsession=sessionMap.get(userId);if(session!=null&&session.isOpen()){try{session.getBasicRemote().sendText(message);}catch(IOExceptione){log.error("推送消息失败",e);}}}/** * 向所有用户广播消息 */publicstaticvoidbroadcast(Stringmessage){sessionMap.values().forEach(session->{try{session.getBasicRemote().sendText(message);}catch(IOExceptione){log.error("广播消息失败",e);}});}/** * 获取在线用户数 */publicstaticintgetOnlineCount(){returnsessionMap.size();}}

四、服务端主动推送消息

在 Controller 中调用 WebSocket 推送消息:

@RestController@RequestMapping("/push")publicclassPushController{/** * 推送给指定用户 */@PostMapping("/user/{userId}")publicResultVOpushToUser(@PathVariableStringuserId,@RequestBodyStringmessage){WebSocketServer.sendToUser(userId,message);returnResultVO.success("推送成功");}/** * 广播给所有用户 */@PostMapping("/broadcast")publicResultVObroadcast(@RequestBodyStringmessage){WebSocketServer.broadcast(message);returnResultVO.success("广播成功");}/** * 获取在线人数 */@GetMapping("/online")publicResultVOgetOnlineCount(){returnResultVO.success(WebSocketServer.getOnlineCount());}}

五、前端页面连接 WebSocket

<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>WebSocket 消息推送</title></head><body><h3>WebSocket 实时消息</h3><div><inputtype="text"id="userId"placeholder="用户ID"value="user001"><buttononclick="connect()">连接</button><buttononclick="disconnect()">断开</button></div><divstyle="margin-top:10px;"><divid="messages"style="border:1px solid #ccc;height:300px;overflow-y:scroll;padding:10px;"></div></div><script>letwebsocket=null;functionconnect(){constuserId=document.getElementById('userId').value;websocket=newWebSocket('ws://localhost:8080/ws/'+userId);websocket.onopen=function(){appendMessage('✅ 连接成功,用户ID: '+userId);};websocket.onmessage=function(event){appendMessage('📩 收到消息: '+event.data);};websocket.onclose=function(){appendMessage('❌ 连接已断开');};websocket.onerror=function(error){appendMessage('⚠️ 连接出错');};}functiondisconnect(){if(websocket){websocket.close();}}functionappendMessage(msg){constdiv=document.getElementById('messages');div.innerHTML+='<div>'+msg+'</div>';div.scrollTop=div.scrollHeight;}</script></body></html>

六、实战:系统通知推送

实际项目中,在业务代码中调用推送:

@ServicepublicclassOrderService{publicvoidcreateOrder(Orderorder){// 1. 保存订单orderMapper.insert(order);// 2. 推送通知给用户JSONObjectmsg=newJSONObject();msg.put("type","order_notify");msg.put("orderId",order.getId());msg.put("message","您的订单已创建成功");WebSocketServer.sendToUser(order.getUserId().toString(),msg.toJSONString());}}

客户端收到消息后,根据type字段做相应处理:

websocket.onmessage=function(event){constdata=JSON.parse(event.data);if(data.type==='order_notify'){showNotification('📦 '+data.message);}elseif(data.type==='system_notify'){showNotification('🔔 '+data.message);}};

七、常见问题

1. WebSocket 连接被拦截

如果项目中有拦截器,需要放行 WebSocket 请求:

registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/ws/**");// 放行 WebSocket

2. 跨域问题

@BeanpublicServerEndpointExporterserverEndpointExporter(){returnnewServerEndpointExporter();}// WebSocket 原生不支持跨域配置// SpringBoot 方式需要在配置中添加@BeanpublicWebSocketConfigurerwebSocketConfigurer(){returnregistry->registry.addHandler(webSocketHandler(),"/ws/{userId}").setAllowedOrigins("*");}

3. 心跳保活

WebSocket 长时间空闲可能被断开,定期发送心跳包:

// 客户端每 30 秒发送心跳setInterval(()=>{if(websocket&&websocket.readyState===WebSocket.OPEN){websocket.send('ping');}},30000);

总结

WebSocket 是实时消息推送的首选方案。SpringBoot 整合 WebSocket 非常简单,三步走:

  1. 引入依赖+配置
  2. 编写 WebSocketServer—— @OnOpen、@OnClose、@OnMessage
  3. 业务代码调用推送—— 面向指定用户或广播

如果对你有帮助,欢迎点赞、评论、关注【张老师技术栈】,持续分享 Java/Python/爬虫 实战干货。

http://www.jsqmd.com/news/1040011/

相关文章:

  • 豆包Seed2.0Lite实测:轻量化AI如何在办公本上稳定运行
  • 微信数据解密技术解析:3分钟掌握密钥提取的核心原理
  • 工业触摸一体机在高温车间频繁死机怎么办?实战排查与选型方案
  • OpenArk:当逆向工具遭遇安全软件的“善意“误判
  • 2026年推荐哈尔滨工程拆除回收/哈尔滨电机回收行业标杆公司 - 品牌宣传支持者
  • ReadCat小说阅读器:打造纯净无干扰的数字阅读体验终极指南
  • 3个步骤获取Steam创意工坊模组:WorkshopDL图形化下载解决方案
  • 41 · 自建中央厨房——从阿明的“OpenAI 又被封 + 数据不能出云“,看 AI 私有化部署 —— **5 大部署形态 + 4 大推理框架 + 量化 / 微调 / GPU 利用率 + 成
  • CMOS运放MCP6H01/2/4:低功耗与高精度的工程实践指南
  • YOLOv8高级能力解析:统一检测/分割/姿态/旋转框的工程落地实践
  • 从隐患排查到渗透测试:构建系统化网络安全评估实战框架
  • 金融企业级漏洞管理实战:从NESSUS扫描到修复闭环的完整指南
  • API中转站原理拆解:AI编程工具实现请求路由与协议转换的4个关键机制
  • 嵌入式通信底层解析:I2C参数RAM与PIP接口硬件机制与实战
  • Gemini3注册失败原因揭秘:AI服务接入的信任机制解析
  • 设备忙闲不均,产能每年悄悄被吃掉15%,APS智能排产如何解?
  • 2026年诚信的打包服务搬家/搬家/上门搬家/重庆打包服务搬家性价比高的公司 - 行业平台推荐
  • TWR-S08UNIV开发板:模块化8位MCU平台硬件解析与开发实战
  • macOS自动点击器终极指南:轻松实现重复任务自动化
  • 2026年比较好的川味钵钵鸡/冷锅钵钵鸡公司对比推荐 - 品牌宣传支持者
  • 7+ Taskbar Tweaker:5个步骤彻底改造Windows任务栏体验
  • 上千台设备管理全靠Excel?物联网设备运维的痛你不懂
  • MPC8360EA MDS板卡复位、时钟与BCSR寄存器配置详解
  • ATmega128嵌入式开发:RISC架构、外设实战与低功耗设计
  • 156、手机摄像头模组结构拆解:从保护盖到 FPC 连接器的完整装配剖面
  • ComfyUI与OpenClaw协同部署:Mac M系列芯片稳定运行七坑详解
  • 2026年诚信的学校搬迁/重庆公司搬迁/搬迁/重庆档案室搬迁哪家正规 - 品牌宣传支持者
  • MPC8240消息单元与I2O接口架构解析及I2C驱动实现
  • TDM接口硬件设计:从PSTN卡原理图解析电信级语音交换系统
  • Microchip 25AA256/25LC256 SPI EEPROM选型、硬件连接与软件驱动全解析