当前位置: 首页 > news >正文

在vue中使用SockJS实现webSocket通信

最近接到一个业务需求,需要做一个聊天信息的实时展示的界面,这就需要和服务器端建立webSocket连接,从而实现数据的实时获取和视图的实时刷新.在此将我的实现记录下来,希望可以给有同样需求的人一些帮助.废话少说,下面我就来讲一下我的实现过程:

前提

要进行文章中的代码的测试,需要服务端端开发人员配合你,提供相关的通信接口.来完成客户端和服务端的通信.实现通信,我们需要用到另个模块sockjs-client模块和stomjs模块,接下来我会先对这两个模块做一个简单的介绍.

稍后我会写一篇使用NodeJS+SockJS实现视屏弹幕的功能的文章,敬请期待~

关于实时通信

实现实时通信,我们通常有三种方法:

  • ajax轮询 ajax轮询的原理非常简单,让浏览器每隔几秒就像服务器发送一个请求,询问服务器是否有新的信息.
  • http 长轮询 长轮询的机制和ajax轮询差不多,都是采用轮询的方式,不过才去的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起链接后,如果没有消息,就一直不返回response给客户端.知道有新的消息才返回,返回完之后,客户端再此建立连接,周而复始.
  • WebSocket WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议.在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送,不需要繁琐的询问和等待. 从上面的介绍很容易看出来,ajax轮询和长轮询都是非常耗费资源的,ajax轮询需要服务器有很快的处理速度和资源,http长轮询需要有很高的并发,也就是同时接待客户的能力.而WebSocket,只需要经过一次HTTP请求,就可以与服务端进行源源不断的消息收发了.

sockjs-client

sockjs-client是从SockJS中分离出来的用于客户端使用的通信模块.所以我们就直接来看看SockJS. SockJS是一个浏览器的JavaScript库,它提供了一个类似于网络的对象,SockJS提供了一个连贯的,跨浏览器的JavaScriptAPI,它在浏览器和Web服务器之间创建了一个低延迟,全双工,跨域通信通道. 你可能会问,我为什么不直接用原生的WebSocket而要使用SockJS呢?这得益于SockJS的一大特性,一些浏览器中缺少对WebSocket的支持,因此,回退选项是必要的,而Spring框架提供了基于SockJS协议的透明的回退选项。SockJS提供了浏览器兼容性,优先使用原生的WebSocket,如果某个浏览器不支持WebSocket,SockJS会自动降级为轮询.

stomjs

STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的简单文本协议; WebSocket是一个消息架构,不强制使用任何特定的消息协议,它依赖于应用层解释消息的含义. 与HTTP不同,WebSocket是处在TCP上非常薄的一层,会将字节流转化为文本/二进制消息,因此,对于实际应用来说,WebSocket的通信形式层级过低,因此,可以在 WebSocket 之上使用STOMP协议,来为浏览器 和 server间的 通信增加适当的消息语义。

STOMP与WebSocket 的关系:

  1. HTTP协议解决了web浏览器发起请求以及web服务器响应请求的细节,假设HTTP协议不存在,只能使用TCP套接字来编写web应用,你可能认为这是一件疯狂的事情;
  2. 直接使用WebSocket(SockJS)就很类似于使用TCP套接字来编写web应用,因为没有高层协议,就需要我们定义应用间发送消息的语义,还需要确保连接的两端都能遵循这些语义;
  3. 同HTTP在TCP套接字上添加请求-响应模型层一样,STOMP在WebSocket之上提供了一个基于帧的线路格式层,用来定义消息语义.

代码实现

代码中除了最基本的连接,还设置了一个定时器,每隔十秒发送一条数据到服务器端,如果发生错误,catch这个错误,重新建立连接.

// 安装并引入相关模块
import SockJS from  'sockjs-client';  
import  Stomp from 'stompjs';
export default {
    data() {
      return {
        dataList: []
      };
    },
    mounted:function(){
      this.initWebSocket();
    },
    beforeDestroy: function () {
      // 页面离开时断开连接,清除定时器
      this.disconnect();
      clearInterval(this.timer);
    },
    methods: {
      initWebSocket() {
        this.connection();
        let self = this;
        // 断开重连机制,尝试发送消息,捕获异常发生时重连
        this.timer = setInterval(() => {
          try {
            self.stompClient.send("test");
          } catch (err) {
            console.log("断线了: " + err);
            self.connection();
          }
        }, 5000);
      },
      removeTab(targetName) {
        console.log(targetName)
      },
      connection() {
      // 建立连接对象
        this.socket = new SockJS('http://xxxxxx:8089/ws');//连接服务端提供的通信接口,连接以后才可以订阅广播消息和个人消息
        // 获取STOMP子协议的客户端对象
        this.stompClient = Stomp.over(this.socket);
        // 定义客户端的认证信息,按需求配置
        var headers = {
          login: 'mylogin',
          passcode: 'mypasscode',
          // additional header
          'client-id': 'my-client-id'
        };
        // 向服务器发起websocket连接
        this.stompClient.connect(headers,(frame) => {
          this.stompClient.subscribe('/topic/chat_msg', (msg) => { // 订阅服务端提供的某个topic
           consolel.log(msg.body);  // msg.body存放的是服务端发送给我们的信息
          });
        }, (err) => {
            // 连接发生错误时的处理函数
            console.log(err);
        });

      },
      // 断开连接
      disconnect() {
        if (this.stompClient != null) {
          this.stompClient.disconnect();
          console.log("Disconnected");
        }
      }
    }
};
复制代码

结语

不知道我是否有写明白,我才疏学浅,表达能力有限,如果有不明白的地方,可发送疑问到我的邮箱2510909248@qq.com,另外如果有什么好的意见或者建议,也欢迎骚扰~~~

参考链接

websocket:支持 前端连接 + 订阅

SockJS简单介绍

STOMP 客户端 API 整理

往期文章

postMessage可太有用了

Expires, Last-Modified, Etag缓存机制

手把手教你制作表格表头悬浮(table-header-fixed)

转载于:https://juejin.im/post/5b7fd02d6fb9a01a196f6276

相关文章:

  • 虚度的日子们
  • Service 保活法之一
  • 新手学习SQL 注入式***
  • ajax取到数据后如何拿到data.data中的属性值
  • python中的魔术属性与魔法方法
  • 转:Android HttpClient基本使用方法
  • Uber开源其大规模指标平台M3
  • Java面试004-框架篇
  • Linux下调试工具
  • npm和node的版本过低时的解决办法
  • Java Specification Requests(JSR,JAVA规范请求)
  • 多版本并发控制MVCC
  • ios中timer相关的延时调用需要注意的地方
  • BeanFactory与FactoryBean
  • LC_CTYPE,LC_ALL,LANG
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 《剑指offer》分解让复杂问题更简单
  • 【comparator, comparable】小总结
  • ComponentOne 2017 V2版本正式发布
  • E-HPC支持多队列管理和自动伸缩
  • Java-详解HashMap
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • react 代码优化(一) ——事件处理
  • spring security oauth2 password授权模式
  • Spring框架之我见(三)——IOC、AOP
  • 阿里云Kubernetes容器服务上体验Knative
  • 初识 beanstalkd
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 前端
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 山寨一个 Promise
  • 手写双向链表LinkedList的几个常用功能
  • 微服务入门【系列视频课程】
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 正则表达式小结
  • ​低代码平台的核心价值与优势
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (poj1.2.1)1970(筛选法模拟)
  • (WSI分类)WSI分类文献小综述 2024
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .Net Core和.Net Standard直观理解
  • .Net6使用WebSocket与前端进行通信
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .NET是什么
  • .net中生成excel后调整宽度