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中的使用的更多相关文章

  1. SpringBoot+Vue+WebSocket 实现在线聊天

    一.前言 本文将基于 SpringBoot + Vue + WebSocket 实现一个简单的在线聊天功能 页面如下: 在线体验地址:http://www.zhengqingya.com:8101 二 ...

  2. SpringBoot+vue整合websocket

    0.引言 这里我先说下,网上对于websocket的解释有一堆不懂自己查,我这就不做原理解释,只上代码. 1.SpringBoot引入websocket maven 依赖 <dependency ...

  3. Springboot + Websocket + Sockjs + Stomp + Vue + Iview 实现java后端日志显示在前端web页面上

    话不多说,看代码. 一.pom.xml 引入spring boot websocket依赖 <dependency> <groupId>org.springframework. ...

  4. 在vue中如何使用WebSocket 以及nginx代理如何配置WebSocket

    WebSocket WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信.浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输. 浏览器支持情况 现 ...

  5. SpringBoot vue

    springboot 整合vue就行前后端完全分离,监听器,过滤器,拦截器 https://github.com/ninuxGithub/spring-boot-vue-separateA blog ...

  6. springboot+vue前后端分离,nginx代理配置 tomcat 部署war包详细配置

    1.做一个小系统,使用了springboot+vue 基础框架参考这哥们的,直接拿过来用,链接https://github.com/smallsnail-wh/interest 前期的开发环境搭建就不 ...

  7. Springboot + Vue + shiro 实现前后端分离、权限控制

    本文总结自实习中对项目对重构.原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelA ...

  8. Vue 中数据流组件

    好久不见呀,这两年写了很多很多东西,也学到很多很多东西,没有时常分享是因为大多都是我独自思考.明年我想出去与更多的大神交流,再修筑自己构建的内容. 有时候我会想:我们遇到的问题,碰到的界限,是别人给的 ...

  9. SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题(一)

    当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异. 笔者前几天刚好在负责一个项目的权限管理模块,现在权限管理模块已经做完了,我想通过5-6篇文章,来介绍一下项目中遇到的问题以及我的解决方 ...

随机推荐

  1. linux运维、架构之路-Docker快速入门

    一.Docker介绍        Docker是Docker.lnc公司开源的一个基于LXC技术之上构建的Container容器引擎,源代码托管在Github上,基于Go语言并遵从Apache2.0 ...

  2. React Native 中不用手点击,代码实现切换底部tabBar

    参考:https://www.jianshu.com/p/02c630ed7725 tabBar1页面有按钮,点击切换到tabBar2 直接用this.props.navigation.navigat ...

  3. mysql OR运算符 语法

    mysql OR运算符 语法 作用:在 WHERE 子语句中把两个或多个条件结合起来. 语法:SELECT * FROM 表名 WHERE 字段1 运算符 值 OR 字段2 运算符 值 说明:如果第一 ...

  4. #1024-JSP结构

    JSP 结构 网络服务器需要一个JSP引擎,也就是一个容器来处理JSP页面.容器负责截获对JSP页面的请求. JSP容器与Web服务器协同合作,为JSP的正常运行提供必要的运行环境和其他服务,并且能够 ...

  5. 使用xshell远程连接Linux

    Linux系统对于程序员来说并不陌生,对IT技术员来说是一个很好的开发平台,因此掌握Linux系统的操作对于一个程序员来说非常有用.而对于习惯使用windows的人来说直接在Linux系统下进行操作感 ...

  6. es之java删除文档操作

    删除文档操作 @Test public void deleteDocument(){ DeleteResponse response = client.prepareDelete("twit ...

  7. [BZOJ3236]:[Ahoi2013]作业(莫队+分块)

    题目传送门 题目描述 此时已是凌晨两点,刚刚做了$Codeforces$的小$A$掏出了英语试卷.英语作业其实不算多,一个小时刚好可以做完.然后是一个小时可与做完的数学作业,接下来是分别都是一个小时可 ...

  8. 转:SpringMVC常见面试题总结(超详细回答)

    原文:https://blog.csdn.net/a745233700/article/details/80963758  我略微修改了下某些地方 1.什么是Spring MVC ?简单介绍下你对sp ...

  9. nginx + tomcat + memcached 做负载均衡及session同步

    1.nginx配置 # For more information on configuration, see: # * Official English Documentation: http://n ...

  10. 004-unity3d MonoBehaviour脚本方法简介

    一.MonoBehaviour 1.公共方法 CancelInvoke Cancels all Invoke calls on this MonoBehaviour. Invoke Invokes t ...