热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

websocket在springboot+vue中的使用教程

这篇文章主要介绍了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> userSessiOnMap= new ConcurrentHashMap<>();
  /**
   * concurrent包的线程安全Map,用来存放每个客户端对应的MyWebSocket对象。
   */
  private static ConcurrentHashMap websocketMap = new ConcurrentHashMap<>();
  /**
   * key: sessionId value: userId
   */
  private static ConcurrentHashMap 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 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 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 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中的使用教程,希望对大家有所帮助,如果大家有任何疑问欢迎给大家留言,小编会及时回复大家的!


推荐阅读
  • 本文详细解析了JSONP(JSON with Padding)的跨域机制及其工作原理。JSONP是一种通过动态创建``标签来实现跨域请求的技术,其核心在于利用了浏览器对``标签的宽松同源策略。文章不仅介绍了JSONP的产生背景,还深入探讨了其具体实现过程,包括如何构造请求、服务器端如何响应以及客户端如何处理返回的数据。此外,还分析了JSONP的优势和局限性,帮助读者全面理解这一技术在现代Web开发中的应用。 ... [详细]
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • 随着Linux操作系统的广泛使用,确保用户账户及系统安全变得尤为重要。用户密码的复杂性直接关系到系统的整体安全性。本文将详细介绍如何在CentOS服务器上自定义密码规则,以增强系统的安全性。 ... [详细]
  • 服务器虚拟化存储设计,完美规划储存与资源,部署高性能虚拟化桌面
    规划部署虚拟桌面环境前,必须先估算目前所使用实体桌面环境的工作负载与IOPS性能,并慎选储存设备。唯有谨慎估算贴近实际的IOPS性能,才能 ... [详细]
  • JavaScript 跨域解决方案详解
    本文详细介绍了JavaScript在不同域之间进行数据传输或通信的技术,包括使用JSONP、修改document.domain、利用window.name以及HTML5的postMessage方法等跨域解决方案。 ... [详细]
  • 搭建个人博客:WordPress安装详解
    计划建立个人博客来分享生活与工作的见解和经验,选择WordPress是因为它专为博客设计,功能强大且易于使用。 ... [详细]
  • 调试利器SSH隧道
    在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需要通过线上域名才能正常访问。但我们一般都会在本地开发,因为这能快速的看到 ... [详细]
  • 解决PHP项目在服务器无法抓取远程网页内容的问题
    本文探讨了在使用PHP进行后端开发时,遇到的一个常见问题:即在本地环境中能够正常通过CURL获取远程网页内容,但在服务器上却无法实现。我们将分析可能的原因并提供解决方案。 ... [详细]
  • h5调用本地摄像头和麦克风一
    h5调用本地摄像头和麦克风一,Go语言社区,Golang程序员人脉社 ... [详细]
  • 微信小程序详解:概念、功能与优势
    微信公众平台近期向200位开发者发送了小程序的内测邀请。许多人对微信小程序的概念还不是很清楚。本文将详细介绍微信小程序的定义、功能及其独特优势。 ... [详细]
  • 本文汇集了我在网络上搜集以及在实际面试中遇到的前端开发面试题目,并附有详细解答。无论是初学者还是有一定经验的开发者,都应深入理解这些问题背后的原理,通过系统学习和透彻研究,逐步形成自己的知识体系和技术框架。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • HTML5 WebSocket技术详解与应用前景
    WebSocket 是 HTML5 引入的一种在单一 TCP 连接上实现全双工通信的技术。作为一种高效且低延迟的协议,WebSocket 允许服务器和客户端之间进行实时双向数据交换。该技术不仅简化了开发过程,还显著提升了 Web 应用的性能和用户体验。未来,随着更多应用场景的探索,WebSocket 在实时通信领域的应用前景将更加广阔。 ... [详细]
  • 在CentOS 7上部署WebRTC网关Janus
    在CentOS 7上部署WebRTC网关Janus ... [详细]
author-avatar
yangaien
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有