若依集成 WebSocket

﹏ヽ暗。殇╰゛Y 2023-01-19 03:23 77阅读 0赞

若依集成 WebSocket

  • 引入依赖
  • 创建 WebSocket 配置类,开启 WebSocket 支持
  • 添加 WebSocketServer 类,创建 webSocket 端点
  • 创建 controller,用于模拟服务端消息发送
  • 添加 websocket.html
  • 参考链接

由于若依模块划分的很清楚,建议将 WebSocket 配置代码放到 framework 模块中,
将 WebSocket 控制器的代码放到用到的模块中。

引入依赖

xxx-framework 下的 pom.xml 中引入 websocket 的依赖:

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

创建 WebSocket 配置类,开启 WebSocket 支持

xxx-framework 下的 com.xxx.framework.config 包下添加该类:

  1. package com.lrjas.framework.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  5. /** * 开启WebSocket支持 */
  6. @Configuration
  7. public class WebSocketConfig {
  8. @Bean
  9. public ServerEndpointExporter serverEndpointExporter() {
  10. return new ServerEndpointExporter();
  11. }
  12. }

添加 WebSocketServer 类,创建 webSocket 端点

  1. package com.lrjas.framework.ws;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.stereotype.Component;
  5. import javax.websocket.*;
  6. import javax.websocket.server.PathParam;
  7. import javax.websocket.server.ServerEndpoint;
  8. import java.io.IOException;
  9. import java.util.concurrent.CopyOnWriteArraySet;
  10. // @ServerEndpoint 声明并创建了webSocket端点, 并且指明了请求路径
  11. // id 为客户端请求时携带的参数, 用于服务端区分客户端使用
  12. @ServerEndpoint("/WebSocketServer/{sid}")
  13. @Component
  14. public class WebSocketServer {
  15. // 日志对象
  16. private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
  17. // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  18. private static int onlineCount = 0;
  19. // concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
  20. private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
  21. // private static ConcurrentHashMap<String,WebSocketServer> websocketList = new ConcurrentHashMap<>();
  22. // 与某个客户端的连接会话,需要通过它来给客户端发送数据
  23. private Session session;
  24. // 接收sid
  25. private String sid = "";
  26. /* * 客户端创建连接时触发 * */
  27. @OnOpen
  28. public void onOpen(Session session, @PathParam("sid") String sid) {
  29. this.session = session;
  30. webSocketSet.add(this); // 加入set中
  31. addOnlineCount(); // 在线数加1
  32. log.info("有新窗口开始监听:" + sid + ", 当前在线人数为" + getOnlineCount());
  33. this.sid = sid;
  34. try {
  35. sendMessage("连接成功");
  36. } catch (IOException e) {
  37. log.error("websocket IO异常");
  38. }
  39. }
  40. /** * 客户端连接关闭时触发 **/
  41. @OnClose
  42. public void onClose() {
  43. webSocketSet.remove(this); // 从set中删除
  44. subOnlineCount(); // 在线数减1
  45. log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
  46. }
  47. /** * 接收到客户端消息时触发 */
  48. @OnMessage
  49. public void onMessage(String message, Session session) {
  50. log.info("收到来自窗口" + sid + "的信息:" + message);
  51. // 群发消息
  52. for (WebSocketServer item : webSocketSet) {
  53. try {
  54. item.sendMessage(message);
  55. } catch (IOException e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. }
  60. /** * 连接发生异常时候触发 */
  61. @OnError
  62. public void onError(Session session, Throwable error) {
  63. log.error("发生错误");
  64. error.printStackTrace();
  65. }
  66. /** * 实现服务器主动推送(向浏览器发消息) */
  67. public void sendMessage(String message) throws IOException {
  68. log.info("服务器消息推送:"+message);
  69. this.session.getBasicRemote().sendText(message);
  70. }
  71. /** * 发送消息到所有客户端 * 指定sid则向指定客户端发消息 * 不指定sid则向所有客户端发送消息 * */
  72. public static void sendInfo(String message, @PathParam("sid") String sid) throws IOException {
  73. log.info("推送消息到窗口" + sid + ",推送内容:" + message);
  74. for (WebSocketServer item : webSocketSet) {
  75. try {
  76. // 这里可以设定只推送给这个sid的,为null则全部推送
  77. if (sid == null) {
  78. item.sendMessage(message);
  79. } else if (item.sid.equals(sid)) {
  80. item.sendMessage(message);
  81. }
  82. } catch (IOException e) {
  83. continue;
  84. }
  85. }
  86. }
  87. public static synchronized int getOnlineCount() {
  88. return onlineCount;
  89. }
  90. public static synchronized void addOnlineCount() {
  91. WebSocketServer.onlineCount++;
  92. }
  93. public static synchronized void subOnlineCount() {
  94. WebSocketServer.onlineCount--;
  95. }
  96. public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {
  97. return webSocketSet;
  98. }
  99. }

创建 controller,用于模拟服务端消息发送

  1. package com.lrjas.web.wms.controller;
  2. import com.lrjas.common.core.controller.BaseController;
  3. import com.lrjas.framework.ws.WebSocketServer;
  4. import org.apache.shiro.authz.annotation.RequiresPermissions;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.web.bind.annotation.GetMapping;
  7. import org.springframework.web.bind.annotation.PathVariable;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.ResponseBody;
  10. import java.io.IOException;
  11. import java.util.HashMap;
  12. import java.util.Map;
  13. @Controller
  14. @RequestMapping("/wms/websocket")
  15. public class WebSocketController extends BaseController
  16. {
  17. private String prefix = "wms/websocket";
  18. @RequiresPermissions("wms:websocket:view")
  19. @GetMapping()
  20. public String socket() {
  21. return prefix + "/websocket"; // 页面的访问路径
  22. }
  23. @RequiresPermissions("wms:websocket:edit")
  24. //推送数据接口
  25. @ResponseBody
  26. @RequestMapping("/push/{cid}")
  27. public Map<String, Object> pushToWeb(@PathVariable String cid, String message) {
  28. if (message == null) {
  29. message = "我是消息!!!";
  30. }
  31. Map<String, Object> result = new HashMap<>();
  32. try {
  33. WebSocketServer.sendInfo(message, cid);
  34. result.put("code", 200);
  35. result.put("msg", "success");
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. return result;
  40. }
  41. }

添加 websocket.html

HTML5 提供了对 websocket 的支持,并且提供了相关 api, 可以直接使用:

1.WebSocket 创建

  1. // url就是服务端的websocket端点路径, protocol 是可选的,指定了可接受的子协议
  2. var Socket = new WebSocket(url, [protocol] );

2.WebSocket 事件































事件 事件处理程序 描述
open Socket.onopen 连接建立时触发
message Socket.onmessage 客户端接收服务端数据时触发
error Socket.onerror 通信发生错误时触发
close Socket.onclose 连接关闭时触发

3.WebSocket 方法


















方法 描述
Socket.send() 使用连接发送数据
Socket.close() 关闭连接

路径由控制器中代码决定:resources/templates/wms/websocket/websocket.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>websocket测试</title>
  6. <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
  7. </head>
  8. <body>
  9. <button onclick="onSendButtonClick()">发送</button>
  10. <button onclick="onJhButtonClick()">交互</button>
  11. <div id="content"></div>
  12. </body>
  13. <script type="text/javascript"> var ws; // 检测浏览器是否支持webSocket if (typeof(WebSocket) == "undefined") { $("#content").html("您的浏览器不支持webSocket!"); console.log("您的浏览器不支持WebSocket!"); } else { $("#content").html("您的浏览器支持webSocket!"); console.log("您的浏览器支持WebSocket!"); //模拟产生clientID let clientID = Math.ceil(Math.random()*100); // 创建 WebSocket 对象, 注意请求路径!!!! ws = new WebSocket("ws://localhost:6300/WebSocketServer/1"); // 与服务端建立连接时触发 ws.onopen = function() { $("#content").append("<p>与服务端建立连接建立成功!您的客户端ID=" + clientID + "</p>"); console.log("Socket 已打开"); //模拟发送数据到服务器 ws.send("你好服务端!我是客户端 "+clientID); }; // 接收到服务端消息时触发 ws.onmessage = function(msg) { $("#content").append("<p>接收到服务端消息:" + msg.data + "</p>"); console.log("获得消息:" + msg.data); // 发现消息进入, 开始处理前端触发逻辑 }; // 关闭事件 ws.onclose = function() { console.log("Socket已关闭"); }; // 发生了错误事件 ws.onerror = function() { alert("Socket发生了错误"); // 此时可以尝试刷新页面 } } function onSendButtonClick(){ console.log("开始发送"); ws.send("这是来自客户端的消息" + location.href + " " + new Date()); } function onJhButtonClick(){ $.ajax({ url: "/wms/websocket/push/2", data: { "message" : "我是消息" }, type: "post", processData: false, contentType: false, success: function(result) { console.log(result); alert(result.msg); } }) } </script>
  14. </html>

运行测试:
在这里插入图片描述
点击【发送】按钮:
在这里插入图片描述

参考链接

  • springboot2 集成 websocket,实现服务端推送消息到客户端
  • 若依 springboot 集成 websocket

发表评论

表情:
评论列表 (有 0 条评论,77人围观)

还没有评论,来说两句吧...

相关阅读