websocket在springboot+vue中的使用教程
1、websocket在springboot中的一种实现
在java后台中,websocket是作为一种服务端配置,其配置如下
@Configuration public class WebSocketConfig { @Bean(name="serverEndpointExporter") public ServerEndpointExporter getServerEndpointExporterBean(){ return new ServerEndpointExporter(); } }
加入上面的配置之后就可以编辑自己的websocket实现类了,如下
@Component @ServerEndpoint(value = "/messageSocket/{userId}") public class MessageWebSocket { private static final Logger logger = LoggerFactory.getLogger(MessageWebSocket.class); /** * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 */ private static int onlineCount = 0; /** * key: userId value: sessionIds */ private static ConcurrentHashMap<Integer, ConcurrentLinkedQueue<String>> userSessionMap = new ConcurrentHashMap<>(); /** * concurrent包的线程安全Map,用来存放每个客户端对应的MyWebSocket对象。 */ private static ConcurrentHashMap<String, MessageWebSocket> websocketMap = new ConcurrentHashMap<>(); /** * key: sessionId value: userId */ private static ConcurrentHashMap<String, Integer> sessionUserMap = new ConcurrentHashMap<>(); /** * 当前连接会话,需要通过它来给客户端发送数据 */ private Session session; /** * 连接建立成功调用的方法 * */ @OnOpen public void onOpen(Session session, @PathParam("userId") Integer userId) { System.out.println(applicationContext); try { this.session = session; String sessionId = session.getId(); //建立userId和sessionId的关系 if(userSessionMap.containsKey(userId)) { userSessionMap.get(userId).add(sessionId); }else{ ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>(); queue.add(sessionId); userSessionMap.put(userId, queue); } sessionUserMap.put(sessionId, userId); //建立sessionId和websocket引用的关系 if(!websocketMap.containsKey(sessionId)){ websocketMap.put(sessionId, this); addOnlineCount(); //在线数加1 } }catch (Exception e){ logger.error("连接失败"); String es = ExceptionUtils.getFullStackTrace(e); logger.error(es); } } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { String sessionId = this.session.getId(); //移除userId和sessionId的关系 Integer userId = sessionUserMap.get(sessionId); sessionUserMap.remove(sessionId); if(userId != null) { ConcurrentLinkedQueue<String> sessionIds = userSessionMap.get(userId); if(sessionIds != null) { sessionIds.remove(sessionId); if (sessionIds.size() == 0) { userSessionMap.remove(userId); } } } //移除sessionId和websocket的关系 if (websocketMap.containsKey(sessionId)) { websocketMap.remove(sessionId); subOnlineCount(); //在线数减1 } } /** * 收到客户端消息后调用的方法 * * @param messageStr 客户端发送过来的消息 **/ @OnMessage public void onMessage(String messageStr, Session session, @PathParam("userId") Integer userId) throws IOException { } /** * * @param session * @param error 当连接发生错误时的回调 */ @OnError public void onError(Session session, Throwable error) { String es = ExceptionUtils.getFullStackTrace(error); logger.error(es); } /** * 实现服务器主动推送 */ public void sendMessage(String message, Integer toUserId) throws IOException { if(toUserId != null && !StringUtil.isEmpty(message.trim())){ ConcurrentLinkedQueue<String> sessionIds = userSessionMap.get(toUserId); if(sessionIds != null) { for (String sessionId : sessionIds) { MessageWebSocket socket = websocketMap.get(sessionId); socket.session.getBasicRemote().sendText(message); } } }else{ logger.error("未找到接收用户连接,该用户未连接或已断开"); } } public void sendMessage(String message, Session session) throws IOException { session.getBasicRemote().sendText(message); } /** *获取在线人数 */ public static synchronized int getOnlineCount() { return onlineCount; } /** *在线人数加一 */ public static synchronized void addOnlineCount() { MessageWebSocket.onlineCount++; } /** *在线人数减一 */ public static synchronized void subOnlineCount() { MessageWebSocket.onlineCount--; } }
到此后台服务端的工作已经做好了,前端如何作为客户端进行连接呢,请继续往下看。。
为了实现断开自动重连,我们使用的reconnecting-websocket.js
组件
//websocket连接实例 let websocket = null; //初始话websocket实例 function initWebSocket(userId) { // ws地址 -->这里是你的请求路径 let host = urlConfig.wsUrl + 'messageSocket/' + userId; if ('WebSocket' in window) { websocket = new ReconnectingWebSocket(host); // 连接错误 websocket.onerror = function () { } // 连接成功 websocket.onopen = function () { } // 收到消息的回调,e.data为收到的信息 websocket.onmessage = function (e) { } // 连接关闭的回调 websocket.onclose = function () { } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function () { closeWebSocket(); } } else { alert('当前浏览器不支持websocket') return; } } //关闭WebSocket连接 function closeWebSocket() { websocket.close(); } //发送消息 function sendMessage(message){ websocket.send(message); }
至此一个简易的完整的websocket已经完成了,具体功能可以依此为基本进行扩展。
总结
以上所述是小编给大家介绍的websocket在springboot+vue中的使用教程,希望对大家有所帮助,如果大家有任何疑问欢迎给大家留言,小编会及时回复大家的!
相关文章
springBoot集成mybatis 转换为 mybatis-plus方式
这篇文章主要介绍了springBoot集成mybatis 转换为 mybatis-plus方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-12-12Spring Boot中RedisTemplate的使用示例详解
RedisTemplate.opsForHash()是RedisTemplate类提供的用于操作Hash类型的方法,它可以用于对Redis中的Hash数据结构进行各种操作,如设置字段值、获取字段值、删除字段值等,本文介绍Spring Boot中RedisTemplate的使用,感兴趣的朋友一起看看吧2023-10-10java使用短信设备发送sms短信的示例(java发送短信)
这篇文章主要介绍了java使用短信设备发送sms短信的示例(java发送短信),需要的朋友可以参考下2014-04-04SpringBoot SpringSecurity JWT实现系统安全策略详解
Spring Security是Spring的一个核心项目,它是一个功能强大且高度可定制的认证和访问控制框架。它提供了认证和授权功能以及抵御常见的攻击,它已经成为保护基于spring的应用程序的事实标准2022-11-11
最新评论