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+Vue+WebSocket 实现在线聊天
一.前言 本文将基于 SpringBoot + Vue + WebSocket 实现一个简单的在线聊天功能 页面如下: 在线体验地址:http://www.zhengqingya.com:8101 二 ...
- SpringBoot+vue整合websocket
0.引言 这里我先说下,网上对于websocket的解释有一堆不懂自己查,我这就不做原理解释,只上代码. 1.SpringBoot引入websocket maven 依赖 <dependency ...
- Springboot + Websocket + Sockjs + Stomp + Vue + Iview 实现java后端日志显示在前端web页面上
话不多说,看代码. 一.pom.xml 引入spring boot websocket依赖 <dependency> <groupId>org.springframework. ...
- 在vue中如何使用WebSocket 以及nginx代理如何配置WebSocket
WebSocket WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信.浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输. 浏览器支持情况 现 ...
- SpringBoot vue
springboot 整合vue就行前后端完全分离,监听器,过滤器,拦截器 https://github.com/ninuxGithub/spring-boot-vue-separateA blog ...
- springboot+vue前后端分离,nginx代理配置 tomcat 部署war包详细配置
1.做一个小系统,使用了springboot+vue 基础框架参考这哥们的,直接拿过来用,链接https://github.com/smallsnail-wh/interest 前期的开发环境搭建就不 ...
- Springboot + Vue + shiro 实现前后端分离、权限控制
本文总结自实习中对项目对重构.原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelA ...
- Vue 中数据流组件
好久不见呀,这两年写了很多很多东西,也学到很多很多东西,没有时常分享是因为大多都是我独自思考.明年我想出去与更多的大神交流,再修筑自己构建的内容. 有时候我会想:我们遇到的问题,碰到的界限,是别人给的 ...
- SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题(一)
当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异. 笔者前几天刚好在负责一个项目的权限管理模块,现在权限管理模块已经做完了,我想通过5-6篇文章,来介绍一下项目中遇到的问题以及我的解决方 ...
随机推荐
- Laya 首日红点逻辑
Laya 首日红点逻辑 @author ixenos 2019-08-26 10:50:27 1.原理:显然,首日红点意味着包含进程销毁的情况,那么就要持久化存储信息,这里我们使用LocalStora ...
- sh_09_格式化输出
sh_09_格式化输出 # 定义字符串变量 name,输出 我的名字叫 小明,请多多关照! name = "大小明" print("我的名字叫 %s,请多多关照!&quo ...
- C++ 对象间通信框架 V2.0 ××××××× 之(五)
类定义: ======================================================================= // MemberFuncPointer.h: ...
- JSP Cookies处理
JSP Cookies处理 Cookies是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JSP显然能够提供对HTTP cookies的支持. 通常有三个步骤来识别回头客 ...
- 记录redis 存放JSON字符串,在并发操作时读-改-写问题
问题描述: 这里涉及到的问题其实就是普遍的读-改-写,redis可以保证每个操作的原子性,但是无法保证多个操作的原子性,解决的方法可以使用redis提供的multi和watch命令,具体使用如下:1. ...
- Spring Cloud架构教程 (六)消息驱动的微服务【Dalston版】
Spring Cloud Stream是一个用来为微服务应用构建消息驱动能力的框架.它可以基于Spring Boot来创建独立的.可用于生产的Spring应用程序.它通过使用Spring Integr ...
- React-Native 之 GD (十四)小时风云榜 及 当前时间操作 及 上一小时、下一小时功能实现
1.小时风云榜 GDHourList.js /** * 小时风云榜 */ import React, { Component } from 'react'; import { StyleSheet, ...
- leetcode-mid-Linked list- 230 Kth Smallest Element in a BST
mycode 81.40% # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x ...
- Django学习之路由系统
一.Django的路由系统 1.URLconf配置 基本格式: 参数说明: 2.正则表达式详解 基本配置 注意事项 补充说明 3.分组命名匹配 URLconf匹配的位置 捕获的参数永远都是字符串 视图 ...
- 纯CSS3写一个立方体并在鼠标悬停的时候无限循环旋转