当前位置:   article > 正文

【Java】SpringBoot快速整合WebSocket实现客户端服务端相互推送信息_java websocket

java websocket

目录

什么是webSocket?

webSocket可以用来做什么?

WebSocket操作类

一:测试客户端向服务端推送消息

1.启动SpringBoot项目

2.打开网站

3.进行测试消息推送

4.后端进行查看测试结果

二:测试服务端向客户端推送消息

1.接口代码

2.使用postman进行调用

3.查看测试结果


什么是webSocket?

        WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。而Http请求只能从客户端请求服务端才能得到响应。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

webSocket可以用来做什么?

        利用双向数据传输的特点可以用来完成很多功能,不需要前端轮询,浪费资源。例如:
聊天功能、数据实时更新和视频弹幕等

webSocket协议
本协议有两部分:握手和数据传输。
握手是基于http协议的。

来自客户端的握手看起来像如下形式:

GET ws://localhost/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat,superchat
Sec-WebSocket-Version: 13

来自服务器的握手看起来像如下形式


HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

SpringBoot快速整合WebSocket代码案例:

下面我就使用SpringBoot快速整合WebSocket实现服务端与客户端的相互推送消息;

代码层级结构


maven依赖

  1. <!--WebSocket的依赖-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-websocket</artifactId>
  5. </dependency>

WebSocket配置类

  1. package com.example.springboot_websocket_demo01;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  5. @Configuration
  6. public class WebSocketConfig {
  7. /**
  8. * 注入ServerEndpointExporter,
  9. * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
  10. */
  11. @Bean
  12. public ServerEndpointExporter serverEndpointExporter() {
  13. return new ServerEndpointExporter();
  14. }
  15. }

WebSocket操作类

通过该类WebSocket可以进行群推送以及单点推送

  1. package com.example.springboot_websocket_demo01;
  2. import jakarta.websocket.*;
  3. import jakarta.websocket.server.PathParam;
  4. import jakarta.websocket.server.ServerEndpoint;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.stereotype.Component;
  7. import java.util.concurrent.ConcurrentHashMap;
  8. import java.util.concurrent.CopyOnWriteArraySet;
  9. @Component
  10. @Slf4j
  11. @ServerEndpoint("/websocket/{userId}") // 接口路径 ws://localhost:8087/webSocket/userId;
  12. public class WebSocket {
  13. //与某个客户端的连接会话,需要通过它来给客户端发送数据
  14. private Session session;
  15. /**
  16. * 用户ID
  17. */
  18. private String userId;
  19. //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
  20. //虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
  21. // 注:底下WebSocket是当前类名
  22. private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
  23. // 用来存在线连接用户信息
  24. private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<String, Session>();
  25. /**
  26. * 链接成功调用的方法
  27. */
  28. @OnOpen
  29. public void onOpen(Session session, @PathParam(value = "userId") String userId) {
  30. try {
  31. this.session = session;
  32. this.userId = userId;
  33. webSockets.add(this);
  34. sessionPool.put(userId, session);
  35. log.info("【websocket消息】有新的连接,总数为:" + webSockets.size());
  36. } catch (Exception e) {
  37. }
  38. }
  39. /**
  40. * 链接关闭调用的方法
  41. */
  42. @OnClose
  43. public void onClose() {
  44. try {
  45. webSockets.remove(this);
  46. sessionPool.remove(this.userId);
  47. log.info("【websocket消息】连接断开,总数为:" + webSockets.size());
  48. } catch (Exception e) {
  49. }
  50. }
  51. /**
  52. * 收到客户端消息后调用的方法
  53. *
  54. * @param message
  55. */
  56. @OnMessage
  57. public void onMessage(String message) {
  58. log.info("【websocket消息】收到客户端消息:" + message);
  59. }
  60. /**
  61. * 发送错误时的处理
  62. *
  63. * @param session
  64. * @param error
  65. */
  66. @OnError
  67. public void onError(Session session, Throwable error) {
  68. log.error("用户错误,原因:" + error.getMessage());
  69. error.printStackTrace();
  70. }
  71. // 此为广播消息
  72. public void sendAllMessage(String message) {
  73. log.info("【websocket消息】广播消息:" + message);
  74. for (WebSocket webSocket : webSockets) {
  75. try {
  76. if (webSocket.session.isOpen()) {
  77. webSocket.session.getAsyncRemote().sendText(message);
  78. }
  79. } catch (Exception e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. }
  84. // 此为单点消息
  85. public void sendOneMessage(String userId, String message) {
  86. Session session = sessionPool.get(userId);
  87. if (session != null && session.isOpen()) {
  88. try {
  89. log.info("【websocket消息】 单点消息:" + message);
  90. session.getAsyncRemote().sendText(message);
  91. } catch (Exception e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. }
  96. // 此为单点消息(多人)
  97. public void sendMoreMessage(String[] userIds, String message) {
  98. for (String userId : userIds) {
  99. Session session = sessionPool.get(userId);
  100. if (session != null && session.isOpen()) {
  101. try {
  102. log.info("【websocket消息】 单点消息:" + message);
  103. session.getAsyncRemote().sendText(message);
  104. } catch (Exception e) {
  105. e.printStackTrace();
  106. }
  107. }
  108. }
  109. }
  110. }

注意:WebSocketConfig和WebSocket必须放在同一层级下,否则Websocket扫描不到ServerEndpoint注解。

一:测试客户端向服务端推送消息

1.启动SpringBoot项目

2.打开网站

WebSocket测试 devTest.run

输入

ws://127.0.0.1:8080/websocket/100

进行连接,测试是否连接成功

3.进行测试消息推送

4.后端进行查看测试结果

测试成功,说明客户端可以使用WebSocket对服务端推送消息。

二:测试服务端向客户端推送消息

1.接口代码

  1. package com.example.springboot_websocket_demo01;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.web.bind.annotation.PostMapping;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. @RequestMapping("/api")
  8. public class YourController {
  9. @Autowired
  10. private WebSocket webSocket;
  11. @PostMapping("/sendNotification")
  12. public void sendNotification() {
  13. try {
  14. // 创建业务消息信息
  15. String message = "postman调用接口访问后端服务器存储数据并使用websocket将消息推送给前端客户端";
  16. // 全体发送
  17. webSocket.sendAllMessage(message);
  18. // 单个用户发送 (userId为用户id)
  19. String userId = "1";
  20. String message1 = "【websocket消息】 单点消息:只发送给id为"+userId+"的用户。";
  21. webSocket.sendOneMessage(userId, message1);
  22. // 多个用户发送 (userIds为多个用户id,逗号‘,’分隔)
  23. String[] userIds = {"1", "2"};
  24. String message2 = "【websocket消息】 单点消息:只发送给id为"+userIds.toString()+"的用户。";
  25. webSocket.sendMoreMessage(userIds, message2);
  26. } catch (Exception e) {
  27. // 输出异常信息
  28. e.printStackTrace();
  29. }
  30. }
  31. }

2.使用postman进行调用

用来模仿客户端发送消息到后端服务器然后返回给客户端。(其实也可以直接在WebSocket类中的onMessage中直接进行操作,调用sendAllMessage等其他方法进行测试);

3.查看测试结果

WebSocket测试 devTest.run

正常结果为

还有很多测试方法,自己可以去思考,以上对于SpringBoot整合WebSocket来说可以算是一个简单的入门案例了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/475689
推荐阅读
相关标签
  

闽ICP备14008679号