行业知识
SpringBoot集成websocket
2026-11-06 10:09:43
来源:互联网转载
websocket
基于 TCP 协议的全双工通信协议,它允许客户端和服务器之间建立持久的、双向的通信连接。
相比传统的 HTTP 请求 - 响应模式,WebSocket 提供了实时、低延迟的数据传输能力。通过 WebSocket,客户端和服务器可以在任意时间点互相发送消息,实现实时更新和即时通信的功能。WebSocket 协议经过了多个浏览器和服务器的支持,成为了现代 Web 应用中常用的通信协议之一。
广泛应用于聊天应用、实时数据更新、多人游戏等场景,为 Web 应用提供了更好的用户体验和更高效的数据传输方式。
Spring Boot 中整合websocket
一、依赖
spring-boot-starter-websocket
springboot-demo com.et 1.0-SNAPSHOT 4.0.0 websocket 8 8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-autoconfigure org.springframework.boot spring-boot-starter-websocket com.alibaba fastjson 2.0.40 compile
二、配置文件和启动类
server: port: 8088
@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }} 三、websocket配置类
@Configuration@EnableWebSocketpublic class WebSocketConfiguration{@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}} 四、websocket服务类
四个事件:
- @OnOpen:标注客户端打开 WebSocket 服务端点调用方法
- @OnClose:标注客户端关闭 WebSocket 服务端点调用方法
- @OnMessage:标注客户端发送消息,WebSocket 服务端点调用方法
- @OnError:标注客户端请求 WebSocket 服务端点发生异常调用方法
@ServerEndpoint("/websocket/{userId}")@Componentpublic class WebSocketServer{private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);//当前在线连接数private static AtomicInteger onlineCount = new AtomicInteger(0);//用来存放每个客户端对应的WebSocketServer对象private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap();//与某个客户端的连接会话,需要通过它给客户端发送数据private Session session;//接收用户userIdprivate String userId = "";//连接建立成功调用的方法 (标注客户端打开 WebSocket 服务端点调用方法)@OnOpenpublic void onOpen(Session session,@PathParam("userId") String userId){this.session = session;this.userId = userId;if(webSocketMap.containsKey(userId)){webSocketMap.remove(userId);webSocketMap.put(userId, this);}else{webSocketMap.put(userId, this); addOnlineCount();}log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());try { sendMessage("连接成功!"); } catch (IOException e) { log.error("用户:" + userId + ",网络异常!!!!!!"); }}//连接关闭调用的方法@OnClosepublic void onClose(){if (webSocketMap.containsKey(userId)) { webSocketMap.remove(userId); subOnlineCount(); } log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());}//收到客户端消息后调用的方法@OnMessage public void onMessage(String message, Session session) { log.info("用户消息:" + userId + ",报文:" + message); if (!StringUtils.isEmpty(message)) { try { JSONObject jsonObject = JSON.parseObject(message); jsonObject.put("fromUserId", this.userId); String toUserId = jsonObject.getString("toUserId"); if (!StringUtils.isEmpty(toUserId) && webSocketMap.containsKey(toUserId)) { webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString()); } else { log.error("请求的 userId:" + toUserId + "不在该服务器上"); } } catch (Exception e) { e.printStackTrace(); } } }//发生错误时调用@OnError public void onError(Session session, Throwable error) { log.error("用户错误:" + this.userId + ",原因:" + error.getMessage()); error.printStackTrace(); }/** * 实现服务器主动推送 */ public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } public static synchronized AtomicInteger getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketServer.onlineCount.getAndIncrement(); } public static synchronized void subOnlineCount() { WebSocketServer.onlineCount.getAndDecrement(); }}测试
打开postman,新建2个websocket测试连接,ws://127.0.0.1:8088/websocket/wupx
点击开启连接按钮,消息记录中会多一条由服务器端发送的连接成功!记录
输入ws://127.0.0.1:8088/websocket/huxy,点击开启连接按钮,然后回到第一次打开的网页在消息框中输入{“toUserId”:“huxy”,“message”:“i love you”},点击发送到服务端,第二个网页中会收到服务端推送的消息{“fromUserId”:“wupx”,“message”:“i love you”,“toUserId”:“huxy”}
控制台输出
2024-02-26 15:26:48.699 INFO 27848 --- [nio-8088-exec-2] c.et.websocket.channel.WebSocketServer : 用户连接:huxy,当前在线人数为:12024-02-26 15:26:56.581 INFO 27848 --- [nio-8088-exec-4] c.et.websocket.channel.WebSocketServer : 用户连接:wupx,当前在线人数为:22024-02-26 15:27:26.401 INFO 27848 --- [nio-8088-exec-5] c.et.websocket.channel.WebSocketServer : 用户消息:wupx,报文:{"toUserId":"huxy","message":"i love you"}
上一篇:服务器底层怎么进系统的?
下一篇:怎么在国外服务器?