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篇文章,来介绍一下项目中遇到的问题以及我的解决方 ...
随机推荐
- 2019年开发App记录
Pod 制作私有库参考 https://www.jianshu.com/p/f903ecf8e882 Pod私有库的升级 改代码部分,到Example文件夹执行pod install ,修改XXX.s ...
- Conturbatio
Conturbatio Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- Fiddler简介以及web抓包1
一.Fiddler简介 简单来说,Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯.网上简介很多,我们不多说. 二.Fiddler版本 Fiddle ...
- [springboot jpa] [bug] Could not open JPA EntityManager for transaction
前言 最近,测试环境遇到了一个问题.经过一番百度加谷歌,终于解决了这个问题.写下这篇博客是为了记录下解决过程,以便以后查看.也希望可以帮助更多的人. 环境 java版本:8 框架:spring clo ...
- [BZOJ3781]:小B的询问(离线莫队算法)
题目传送门 题目描述 小B有一个序列,包含$N$个$1~K$之间的整数.他一共有$M$个询问,每个询问给定一个区间$[L...R]$,求$\sum \limits_{i=1}^{K}c(i)^2$的值 ...
- npm install 成功安装依赖后,运行跑不起来怎么办?
最近接手公司的项目,由于代码历史悠久,据说已经最少经历过了6个人的手,查看gitee提交的年限,竟然是1-2年前的代码,好吧.这个锅总得有人接,既然是架构师,就要勇于面对挑战,今天把我解决的方法记录起 ...
- 转载自:StringUtils的常见方法
转载自:https://blog.csdn.net/simple_smile_sun/article/details/51819158 注:运用StringUtils需要导入相关jar文件,commo ...
- angular6的响应式表单
1:在AppModule模块里面引入 ReactiveFormsModule 要使用响应式表单,就要从@angular/forms包中导入ReactiveFormsModule,并把它添加到你的NgM ...
- Web网站安全
一.防SQL注入 SQL注入,就是在web提交表单,请求参数的字符串中通过注入SQL命令,提交给服务器,从而让服务器执行注入的恶意的SQL命令的行为,是发生在开发程序的数据库层的安全漏洞. SQl注入 ...
- 如何利用EDM邮件营销进行持续推销
一般来说,一个电子商务网站的转化率在2%左右是正常的.这也意味着其他98%的潜在客户并不会购买任何东西,并且可能再也不回来了.这个时候,如何利用EDM邮件营销进行持续推销呢? 首先,EDM邮件营销可以 ...