首页 > 其他分享 >vue+websocket

vue+websocket

时间:2022-09-05 11:11:54浏览次数:73  
标签:HTTP vue WebSocket socket 服务器 websocket 连接

一、websocket是什么

WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被[W3C]定为标准。它算是html5规范中的一个部分,算是一种协议,它借鉴了socket这种思想,为web应用程序客户端和服务端之间(注意是客户端服务端)提供了一种全双工通信机制。同时,它又是一种新的应用层协议,websocket协议是为了提供web应用程序和服务端全双工通信而专门制定的一种应用层协议,通常它表示为:ws://echo.websocket.org/?encoding=text HTTP/1.1,可以看到除了前面的协议名和http不同之外,它的表示地址就是传统的url地址。(ws是不加密的,wss是加密的)

那这种协议是怎么和传统的HTTP1.0或者HTTP/1.1区分开的呢,我从使用过程中截取了一张图片。

image.png

可以看到websocket发起的请求,connection是upgrade,还额外多了upgrade的属性,属性值为websocket,而正常情况短连接的请求,connection都是close的,这才符合http协议下,一个request对应一个response的定义。

服务器也能根据这两个字段,区分websocket请求和其他http请求。

connection: upgrade
urgrade: websocket

简而言之,websocket就是一种新的协议,用来解决实时通信的。首次通信过程借用http的握手动作,建立通道,然后用tcp进行数据传输。

二、为什么要用websocket

在没有websocket之前,开发者们是如何解决这个实时通信的场景的呢。

1、ajax轮询

过程:连接->传输数据->关闭连接

开个定时器,每隔几秒就发起一次请求,询问服务端是否有新数据。

这种方法,一是对服务器压力大(连续请求压力能不大吗),必须要有很快的处理速度,快速响应,会让服务器cpu资源经常被占用,二是总归是有时差(存在间隔时间),要缩短间隔时间做到伪实时通信,那又对服务器压力激增。

2、long poll 长轮询

过程:连接->传输数据->关闭连接

原理和第一点的ajax轮询差不多,都是客户端主动向服务器发起请求,区别就是long poll采用的是阻塞模型,顾名思义,就是会一直占线,直到服务器有消息或者触发超时机制,才会返回response给到客户端,周而复始。

这种方法,发起请求的数量比ajax可少得多了,不过就是会一直占线,这要求服务器必须有很高的并发能力,不然可能会出现,其他正常请求服务器处理不过来的情况。

3、长连接

过程:连接->传输数据->保持连接 -> 传输数据-> ………..->一方关闭连接

HTTP1.1默认是长连接,也就是默认Connection的值就是keep-alive,本次请求响应结束后,TCP连接将仍然保持打开状态,所以浏览器可以继续通过相同的连接发送请求,节省了很多TCP连接建立和断开的消耗,还节约了带宽。

这种长连接的方法,存在几个缺点

a、 keep-alive确实可实现长连接,但是本质上这还是从客户端发起-服务端应答,这种一request一response的模式,不过是省略了每次请求的开启和关闭操作。

b、长连接不代表是永久连接,如果超时了,且连接中没有新消息发出,那这个长连接就会断掉,相应的tcp连接也会被干掉。

4、webscoket

过程:连接->传输数据->保持连接 -> 传输数据-> ………..->一方关闭连接

在WebSocket中,只需要服务器和浏览器通过HTTP协议进行一个握手的动作,然后单独建立一条TCP的通信通道进行数据的传送。WebSocket同HTTP一样也是应用层的协议,但是它是一种双向通信协议,是建立在TCP之上的。

WebSocket的流程大概是以下几步:

a、浏览器、服务器建立TCP连接,三次握手。这是通信的基础,传输控制层,若失败后续都不执行。

b、TCP连接成功后,浏览器通过HTTP协议向服务器传送WebSocket支持的版本号等信息。(开始前的HTTP握手)服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据。确保tcp通信通道建立成功。

c、连接成功后,双方通过TCP通道进行数据传输,不需要HTTP协议。 也就是说WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。

相比上面3种,websocket连接成功后,是能双向传输数据的,既可以是服务端主动发起数据推送,也可以是客户端主动向服务端推送心跳包(划重点)。打破了以往web端,只能一问一答,还得是客户端主动发起请求的模式。这对于实时性要求高的场景来说,在项目中接入webscoket,既确保了实时性,对资源要求也不高,无疑是个很好的选择。

websocket目前的缺点就是,低版本浏览器不兼容。(不过现在应该也不会有人用什么ie9或者更低版本吧)

三、怎么在vue项目中使用

要使用webscoket(项目不需要额外引入),那就得对它各种相关状态,api属性都有一定了解。

首先我们先创建一个websocket对象

// 实例化socket,第一个参数必填,第二个是可选的参数,指定子协议用的
    this.socket = new WebSocket(
      url, [protocol]
    )
复制代码

那这个socket对象就有以下属性

调用方法都是this.socket.【属性名】

image.png

还具备了相关事件,可供调用

image.png

发送数据方法

image.png

知道了这些,下面我们就来vue项目中实操一下吧。

# 由于本人仅是前端,本文就不阐述后端websocket的具体实现,仅叙述前端的实现过程

第一步

在data中创建好相关变量

socket: '', // websocket对象
socketStaus: false, // 断线重新标志位,false可发重连请求,true不可
timeoutObj: null, // 心跳机制状态1
serverTimeoutObj: null, // 心跳机制状态2
复制代码

第二步

创建webscoket初始化函数init,在其中进行socket的实例化,和其他相关事件的监听

init: function() {
  if (typeof WebSocket === 'undefined') {
    alert('您的浏览器不支持socket') // ie9及以下版本不支持,判断一下
  } else {
    // 实例化socket
    this.socket = new WebSocket(
      this.config.data[this.GLOBAL_CONST.MONITOR.WS_URL_FOR_WEB],
    ) // 括号中的值是一个url
    // 监听socket连接
    this.socket.onopen = this.open // 关联到具体函数
    // 监听socket错误信息
    this.socket.onerror = this.error // 关联到具体函数
    // 监听socket关闭
    this.socket.onclose = this.close // 关联到具体函数
    // 监听socket消息
    this.socket.onmessage = this.getMessage // 关联到具体函数
  }
},
复制代码

第三步

创建init中相关调用函数

几个函数如下

open: function() {
  this.longstart() // 成功建立连接后,创建心跳检测
},
error: function() {
  // console.log('连接错误,开始重新连接')
  this.reconnect()
},
close: function() {
  console.log('socket已经关闭,开始重新连接')
  this.reconnect()
},
// ws断线重连
reconnect() {
  if (!this.socketStaus) {
    this.socketStaus = true
    setTimeout(() => {
      console.log('重连 实例化socket 前', this.config)
      // 没连接上会一直重连,设置延迟避免请求过多,设了5秒限流
      this.socket = new WebSocket(
        this.config.data[this.GLOBAL_CONST.MONITOR.WS_URL_FOR_WEB],
      )
      // 监听socket连接
      this.socket.onopen = this.open
      // 监听socket错误信息
      this.socket.onerror = this.error
      // 监听socket关闭
      this.socket.onclose = this.close
      // 监听socket消息
      this.socket.onmessage = this.getMessage

      this.socketStaus = false
    }, 5 * 1000)
  }
},
复制代码

还有最重要的接收数据的函数

// ws获取到数据执行方法
getMessage: function(msg) {
  this.longstart() // 拿到数据也要重置心跳机制
  try {
    const data = JSON.parse(msg.data)
    console.log(msg.data, data)
    // 这里写具体逻辑
  } catch (e) {
    console.log('出错了', e)
    return
  }
},
复制代码

心跳函数

// 心跳机制 建议接入该机制
在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务
器端并没有触发onclose的事件。这样可能会发生服务器会继续向客户端发送数据,并且
这些数据会丢失。所以需要一种机制来检测客户端和服务端是否处于正常的链接状态。因
此就有了websocket的心跳,检测链接的状态。

longstart() {
  // 1、通过关闭定时器和倒计时进行重置心跳
  clearInterval(this.timeoutObj)
  clearTimeout(this.serverTimeoutObj)
  // 2、每隔30s向后端发送一条商议好的数据
  this.timeoutObj = setInterval(() => {
    console.log('重置监测心跳')
    const data = { // 与后端商量好心跳要传递的值
      packageType: 0
    }
    this.websocketsend(JSON.stringify(data))
    // 3、发送数据 2s后没有接收到返回的数据进行关闭websocket重连
    this.serverTimeoutObj = setTimeout(() => {
      console.log('没有心跳了....')
      this.socket.close()
    }, 2000)
  }, 30 * 1000)
},
复制代码

发送数据的函数

 // 发送数据方法
websocketsend(Data) { // 数据发送
  this.socket.send(Data)
}, 
复制代码

第四步

在合适的时机调用init初始化socket对象

比如我项目是一打开就要连接websocket,那我就在挂载阶段调用。

mounted() {
    this.init()
}
复制代码

第五步

退出前记得销毁相关socket对象和心跳定时器

beforeDestroy() {
    // 1、组件销毁时,关闭与服务器的连接
    if (this.socket) {
      this.socket.close() // 离开路由之后断开websocket连接
    }
    // 销毁心跳定时器
    if (this.timeoutObj) {
      clearInterval(this.timeoutObj)
      this.timeoutObj = null
    }
    if (this.serverTimeoutObj) {
      clearTimeout(this.serverTimeoutObj)
      this.serverTimeoutObj = null
    }
}
复制代码

到此,vue项目已经接入websocket啦,小伙伴们有需要可以试一下。

ps,这里是地霊殿-三無,希望能对你们有所帮助。

Snipaste_2022-07-19_15-30-26.jpg


作者:地霊殿__三無
链接:https://juejin.cn/post/7124942304690831368
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:HTTP,vue,WebSocket,socket,服务器,websocket,连接
From: https://www.cnblogs.com/Earth-Hall-Sanwu/p/16657392.html

相关文章

  • mosquitto配置protocol websockets无效,MQTT X或其他程序连接不上
    mqtt(mosquitto)配置protocolwebsockets必须配置socket_domain#mqtt协议配置,分为IP4和IP6两种,当前可以只配置启用一种listener18830.0.0.0socket_domainipv4protoco......
  • vue3——shallowReactive 与 shallowRef
    shallowReactive:只处理对象最外层属性的响应式(浅响应式)。shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。什么时候使用?如果有一个对象数据,结......
  • vue3——toRef
    一.ref与toRef的区别:ref:复制,修改响应式数据不会影响原始数据toRef引用,修改响应式数据会影响原始数据ref:数据发生改变,界面会自动更新toRef:数据发生改变,界面也不会自......
  • Vue学习之--------深入理解Vuex之getters、mapState、mapGetters(2022/9/3)
    这一篇博客的内容是在上一篇博客的基础上进行:深入理解Vuex、原理详解、实战应用@目录1、getters的使用1.1概念1.2用法1.3如何读取数据2、getters在项目中的实际应用3......
  • Vue学习之--------深入理解Vuex之多组件共享数据(2022/9/4)
    在上篇文章的基础上:Vue学习之--------深入理解Vuex之getters、mapState、mapGetters1、在state中新增用户数组2、新增Person.vue组件提示:这里使用nanoid来生成新用户......
  • Vue学习之--------深入理解Vuex之模块化编码(2022/9/4)
    在以下文章的基础上1、深入理解Vuex、原理详解、实战应用:https://blog.csdn.net/weixin_43304253/article/details/1266513682、深入理解Vuex之getters、mapState、mapG......
  • Vue简介
    1.什么是vue官方给出的概念:Vue(读音/vju/,类似于view)是一套用于构建用户界面的前端框架1.构建用户界面用vue往html页面中填充数据,非常的方便2.框架......
  • VUE构建
    VUE渐进式JavaScript框架易学易用基于标准HTML、CSS和JavaScript构建,提供容易上手的API和一流的文档。性能出色经过编译器优化、完全响应式的渲染系统,几乎不......
  • vue3项目-小兔鲜儿笔记-商品详情页01
    1.基础布局完成商品详情基础布局,路由配置,搭好页面架子  2.渲染面包屑编写一个钩子函数useGoods.js,将面包屑获取数据的逻辑抽取出来。//拿到商品信息import{......
  • jQuery和Vue入门
    jQueryjQuery:别人写好的js文件*********jquery中所有东西都是函数:jQuery的放啊发名称:first获取名称的第一个元素名称:last获取名称的最后一个元素*$(documen......