https://www.cnblogs.com/SjhCode/p/WebSocket.html
ruoyi整合WebSocket
这里使用WebSocket目的:向前端推送实时消息,配合ActiveMQ接入三方使用的
导入maven依赖
<!-- WebSocket --> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
注册配置webSocket类
package com.ruoyi.common.websocket; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { /** * ServerEndpointExporter 作用 * * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint * * @return */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
webSocket工具类
package com.ruoyi.common.websocket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import java.util.concurrent.CopyOnWriteArraySet; /** * webSocket工具 */ @Component @ServerEndpoint("/webSocket") public class WebSocket { private Session session; private final static Logger log = LoggerFactory.getLogger(WebSocket.class); private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>(); //Session 的生命周期,onOpen -> onMessage -> onClose @OnOpen public void onOpen(Session session) { this.session = session; webSocketSet.add(this); log.info("【websocket消息】有新的连接, 总数:{}", webSocketSet.size()); } @OnClose public void onClose() { webSocketSet.remove(this); log.info("【websocket消息】连接断开, 总数:{}", webSocketSet.size()); } @OnMessage public void onMessage(String message) { log.info("【websocket消息】收到客户端发来的消息:{}", message); } public void sendMessage(String message) { for (WebSocket webSocket: webSocketSet) { log.info("【websocket消息】广播消息, message={}", message); System.out.println(message); try { webSocket.session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } }
使用时,从三方获取的推送信息,处理完由webSocket推送给前端
webSocket.sendMessage(JSON.toJSONString(XXXDto));
注意:有时候和前端对接会出现异常java.io.EOFException: null ,可能是未配置错误处理,可以加上onError方法
/** * 配置错误信息处理 * @param session * @param t */ @OnError public void one rror(Session session, Throwable t) { //什么都不想打印都去掉就好了 log.info("【websocket消息】出现未知错误 "); //打印错误信息,如果你不想打印错误信息,去掉就好了 //这里打印的也是 java.io.EOFException: null t.printStackTrace(); }
连接时带入userId的写法,将存储webSocket的Set换成Map,由前端传入。(单点发送)
/** * webSocket工具 */ @Component @ServerEndpoint("/webSocket/{userId}") public class WebSocket { private Session session; private final static Logger log = LoggerFactory.getLogger(WebSocket.class); //当前在线人数 private static int onlineCount = 0; private static ConcurrentHashMap<Long, WebSocket> webSocketMap = new ConcurrentHashMap<>(); private Long userId = 0L; //Session 的生命周期,onOpen -> onMessage -> onClose /** * 连接建立成功调用的方法*/ @OnOpen public void onOpen(Session session,@PathParam("userId") Long userId) { this.session = session; this.userId=userId; if(webSocketMap.containsKey(userId)){ webSocketMap.remove(userId); webSocketMap.put(userId,this); //加入set中 }else{ webSocketMap.put(userId,this); //加入set中 addOnlineCount(); //在线数加1 } log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount()); try { sendMessage("连接成功"); } catch (IOException e) { log.error("用户:"+userId+",网络异常!!!!!!"); } } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { if(webSocketMap.containsKey(userId)){ webSocketMap.remove(userId); //从set中删除 subOnlineCount(); } log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息*/ @OnMessage public void onMessage(String message, Session session) { log.info("用户消息:"+userId+",报文:"+message); //可以群发消息 //消息保存到数据库、redis if(StringUtils.isNotEmpty(message)){ try { //解析发送的报文 JSONObject jsonObject = JSON.parseObject(message); //追加发送人(防止串改) jsonObject.put("fromUserId",this.userId); String toUserId=jsonObject.getString("toUserId"); //传送给对应toUserId用户的websocket if(StringUtils.isNotBlank(toUserId)&&webSocketMap.containsKey(toUserId)){ webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString()); }else{ log.error("请求的userId:"+toUserId+"不在该服务器上"); //否则不在这个服务器上,发送到mysql或者redis } }catch (Exception e){ e.printStackTrace(); } } } /** * * @param session * @param error */ @OnError public void one rror(Session session, Throwable error) { log.error("用户错误:"+this.userId+",原因:"+error.getMessage()); error.printStackTrace(); } /** * 实现服务器主动推送,广播 */ public void sendMessage(String message) throws IOException { log.info("广播消息为{}",message); this.session.getBasicRemote().sendText(message); } /** * 发送自定义消息 * */ public void sendInfo(String message,@PathParam("userId") Long userId) throws IOException { log.info("发送消息到:"+userId+",报文:"+message); if(userId!=null&&webSocketMap.containsKey(userId)){ webSocketMap.get(userId).sendMessage(message); }else{ log.error("用户"+userId+",不在线!"); } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocket.onlineCount++; } public static synchronized void subOnlineCount() { WebSocket.onlineCount--; } }标签:WebSocket,log,userId,ruoyi,session,整合,websocket,message,public From: https://www.cnblogs.com/chuangsi/p/17341515.html