vue socketio,vue web socket

  vue socketio,vue web socket

  主要介绍vue-socket.io的教程和踩坑的记录,通过示例代码介绍的非常详细,有一定的参考价值,感兴趣的朋友可以参考一下。

  

目录

  前言我遇到的问题是使用教程安装与介绍(main.js)和使用(Page.vue)结合connect事件存储路由卫士的解决方案拦截的。请允许我先吐槽一句:vue-socket.io相关的中文博客太少了,所以来来去去的也就那么几个。教程比较分散,版本也比较老。即使我进行了激烈的搜索,也无法找到解决问题的方法。然后我就火了,开始看源代码,写测试demo,差不多看完了所有相关的问题。折腾了1天,我终于。做完了,下面总结一下~

  考虑到很多小伙伴看完文章后还是很迷茫或者无法重现方案,所以用了一天时间附上一份https://github.com/dreamsqin/demo-vue-socket.io的demo源代码~给我一个开始吧~如果满意~谢谢

  

前言

  Vue-socket.io实际上是基于socket.io-client的一层封装,Vue实例上挂载了$socket。同时,通过使用sockets对象可以轻松实现基于组件的事件监控,更加方便您在vue项目中使用。我目前用的是vue-socket.io:3.0.7,在它的package.json里可以看到它依赖socket.io-client:2.1.1。

  

我遇到的问题

  websocket连接地址是从后端动态获取的,所以加载页面时还没有创建vueSocketIO实例,通过这个订阅页面时会报错。$socket.emit同时找不到Vue实例的sockets对象(里面写的事件不会被监控,即使后来连接成功)。

  如果你的websocket连接地址是静态的(写死了),可以直接看教程。如果你和我有同样的问题,跳到解决方案。

  控制台报告了以下错误:

  

使用教程

  让我们抛开可能出现的问题,跟随官网的教程:

  

安装

  安装vue-socket.io - save

  

引入(main.js)

  从“vue”导入Vue

  从导入存储。/商店

  从导入应用程序。/App.vue

  从“vue-socket.io”导入VueSocketIO

  Vue.use(新的VueSocketIO({

  debug: true,

  连接:“http://metinseylan.com:1992”,

  vuex: {

  店,

  actionPrefix: SOCKET_ ,

  变异前缀:“套接字_”

  },

  选项:{ path:/my-app/ }//可选选项

  }))

  新Vue({

  路由器,

  店,

  render: h=h(App)

  }).$ mount(“# app”)

  调试:生产环境建议关闭,开发环境可以打开,这样可以在控制台看到一些关于socket连接和事件监控的信息,比如如下:

  连接:连接地址前缀,注意!这里只有前缀。我之前被坑过,因为明明后端已经把上下文还给我了,却莫名其妙的被移除了。vue-socket.io这里用的是socket.io-client的Manager api,关键源代码如下(只看我写中文备注的部分):

  vue-socket.io(索引. js)

  从“socket.io-client”导入socket io;

  导出默认类VueSocketIO {

  /**

  *让我们利用所有资源

  * @param io

  * @param vuex

  * @param调试

  * @param选项

  */

  构造函数({连接,vuex,调试,选项}){

  Logger.debug=debug

  this.io=this.connect(连接,选项);//获取设置的参数后调用connect方法。

  this . useconnectionnamespace=(options选项. useconnectionnamespace);

  this.namespaceName=(options选项. namespace name);

  this.emitter=新发射器(vuex);

  this.listener=新监听器(this.io,this . emitter);

  }

  /**

  *注册SocketIO实例

  * @param连接

  * @param选项

  */

  连接(连接,选项){

  if(连接的连接类型===object) {

  logger . info(` received socket . io-client instance `);

  返回连接;

  } else if(连接类型===string) {

  const io=SocketIO(连接,选项);//实际使用的是socket.io-client的管理器API

  logger . info(` n接收的连接字符串`);

  返回(这个。io=io);

  }否则{

  引发新错误("不支持的连接类型");

  }

  }

  socket.io-client(index.js)

  var url=require( ./URL’);

  函数查找(uri,opts) {

  if (typeof uri===object) {

  opts=uri

  uri=未定义;

  }

  opts=opts { };

  var parsed=URL(uri);//通过url.js对关系前缀进行截取

  var source=parsed.source

  var id=parsed.id

  var path=parsed.path

  var sameNamespace=cache[id]中的缓存[id]路径nsps。

  var新连接=opts。强制新建 选项[强制新连接]

  false===opts。多路复用 相同的命名空间;

  var io

  if (newConnection) {

  调试("忽略%s的套接字缓存",源);

  io=Manager(source,opts);

  }否则{

  如果(!缓存[id]) {

  调试(为%s新建超正析象管实例,来源);

  cache[id]=Manager(source,opts);

  }

  io=缓存[id];

  }

  if (parsed.query!opts.query) {

  opts。查询=已解析。查询;

  }

  返回io.socket(parsed.path,opts);//实际调用的是解析后的前缀地址

  }

  选项。路径:这里就可以填求转发到连接地址的后缀,如果不填会被默认添加/socket.io,关键源码如下(只看我写中文备注的部分就好):

  其他的选择配置可以参见https://socket.io/docs/client-api/

  socket.io-client(manager.js)

  函数管理器(uri,opts) {

  如果(!(经理的)的这个实例返回新的Manager(uri,opts);

  if (uri (object===typeof uri)) {

  opts=uri

  uri=未定义;

  }

  opts=opts { };

  opts。path=opts。path /socket。io’;//看到没有,如果你不传递选项。路径参数的话会被默认安一个尾巴/socket.io

  这个。nsps={ };

  这个。subs=[];

  this.opts=opts

  这个。重新连接(opts。重新连接!==假);

  这个。重新连接尝试(选择。reconnectionattempts Infinity);

  这个。重新连接延迟(选项。重新连接延迟 1000);

  这个。reconnecondelaymax(opts。reconnecondelaymax 5000);

  这个。随机化因子(opts。随机化因子 0.5);

  this.backoff=new Backoff({

  min: this.reconnectionDelay(),

  max: this.reconnectionDelayMax(),

  抖动:这个。随机化因子()

  });

  这个。超时(null==opts。暂停?20000年:opts。暂停);

  this.readyState=已关闭

  this.uri=uri

  这个。正在连接=[];

  this.lastPing=null

  this.encoding=false

  这个。数据包缓冲区=[];

  var _ parser=opts。解析器 解析器;

  this.encoder=new _parser .编码器();

  this.decoder=new _parser .解码器();

  这个。autoconnect=opts。自动连接!==假;

  如果(这个。自动连接)这个。open();

  }

  vuex:配置后可以在商店。射流研究…的突变或者行动监听到vue-套接字。超正析象管事件(例如:连接、断开、重新连接等),这部分目前用得比较少,也挺简单,如果有疑问可以给我留言我再单独提供教程。

  

使用(Page.vue)

  注意:熟悉插座。碘客户端的应该知道,默认情况下,websocket在创建实例的时候就会自动发起连接了,所以切记不要在组件中重复发起连接。如果你想自己控制发起连接的时机可以将选项。自动连接设置为错误。

  导出默认值{

  名称:页面,

  套接字:{//通过某视频剪辑软件实例对象套接字实现组件中的事件监听

  connect: function () {//套接字的连接事件

  console.log("从页面连接的套接字")

  },

  STREAM_STATUS(data) {//后端按主题名推送的消息数据

  console.log(Page: data )

  }

  },

  已安装(){

  console.log(页面装载)

  这个. socket.emit(STREAM_STATUS ,{ subscribe: true })//在页面加载时发起订阅,"流状态"是你跟后端约定好的主题名

  }

  }

  事件除了在套接字对象中默认监听,你还可以在外部单独注册事件监听或取消注册:

  this.sockets.subscribe(事件名称,(数据)={

  这个。msg=数据。消息;

  });

  这个。插座。取消订阅(事件名称).

  但这种方式从源码上看是不支持参数传递的,只支持传递事件名及回调函数(部分源码如下):

  vue-Socket.io(mixin.js)

  创建之前(){

  如果(!这个。插座)这个。套接字={ };

  如果(键入此. vueSocketIo===object) {

  for(const对象。键的命名空间(这个.$vueSocketIo)) {

  这个。插座[名称空间]={

  订阅:(事件,回调)={

  这个. vueSocketIo[命名空间]。发射器。添加监听器(事件、回调、this);

  },

  取消订阅:(事件)={

  这个. vueSocketIo[命名空间]。发射器。移除监听器(事件,this);

  }

  }

  }

  }否则{

  这个10.99美元vuesocketio。发射器。添加监听程序(事件、回调、这个);

  这个10.99美元vuesocketio。发射器。移除监听器(事件,this);

  }

  }

  

解决方案

  针对我上面描述的问题,最大原因就在于获取窝连接地址是异步请求,如文章开头的截图,页面安装打印时,这个。$套接字还是未定义。所以我们要做的就是怎么样让页面加载在VueSocketIO实例创建之后。

  我提供两种解决方案,具体怎么选择看你们的需求~

  保证拿到窝连接地址后再将某视频剪辑软件实例挂载到应用

  缺点:如果你获取窝地址的请求失败了,整个项目的页面都加载不出来(一般服务器出现问题才会有这种情况产生)

  优点:实现简单,一小段代码挪个位置就好

  主页。射流研究…

  从“vue”导入某视频剪辑软件

  从导入应用程序 App.vue

  从导入路由器。/路由器

  从导入存储。/商店

  从" @/api/Parent "导入ParentApi

  从" vue-socket.io "导入VueSocketIO

  /* 使用vue-socket.io */

  ParentApi.getSocketUrl().然后((res)={

  Vue.use(新的VueSocketIO({

  调试:假,

  连接:res.data.path,

  选项:{ path: /my-project/socket.io }

  }))

  新Vue({

  路由器,

  店,

  render: h=h(App)

  }).$ mount("# app ")

  })

  控制台打印如下图:

  

结合connect事件+store+路由守卫实现拦截

  原理:异步请求回调中创建VueSocketIO实例并监听连接事件,监听回调中修改isSuccessConnect参数的值,在页页面路由中增加输入前守卫,利用设置间隔周期性判断isSuccessConnect的值,满足条件则取消定时执行并路由跳转。

  缺点:实现起来稍微复杂一点

  优点:不会影响其他页面的加载

  主页。射流研究…

  从“vue”导入某视频剪辑软件

  从导入应用程序 App.vue

  从导入路由器。/路由器

  从导入存储。/商店

  从" @/api/Parent "导入ParentApi

  从" vue-socket.io "导入VueSocketIO

  ParentApi.getSocketUrl().然后((res)={

  let vueSocketIo=new vueSocketIo({

  调试:假,

  连接:res.data.path,

  选项:{ path: /my-project/socket.io }

  })

  //监听连接事件,设置isSuccessConnect为真实的

  vueSocketIo.io.on(connect ,()={

  console.log(从主页. js进行套接字连接)

  商店。提交( newIsSuccessConnect ,true)

  })

  Vue.use(vueSocketIo)

  })

  新Vue({

  路由器,

  店,

  render: h=h(App)

  }).$ mount("# app ")

  商店。射流研究…

  从“vue”导入某视频剪辑软件

  从" vuex "导入状态管理

  Vue.use(Vuex)

  导出默认的新Vuex .商店({

  状态:{

  //套接字连接状态

  isSuccessConnect: false

  },

  突变:{

  newIsSuccessConnect(状态,值){

  state.isSuccessConnect=value

  }

  },

  getters: {

  getIsSuccessConnect: state={

  返回state.isSuccessConnect

  }

  },

  动作:{

  }

  })

  router.js

  从“vue”导入某视频剪辑软件

  从“vue路由器"导入路由器

  从导入存储。/商店

  Vue.use(路由器)

  导出默认新路由器({

  模式:"历史",

  base: process.env.BASE_URL,

  路线:[

  {

  路径:"/page ",

  名称:页面,

  component:()=import(/* webpackChunkName: Page */ ./页/页。vue’),

  输入前:(收件人,发件人,下一个)={

  设intervalId=setInterval(()={

  //直到商店中isSuccessConnect为真实的时才能进入/页面

  if(store . getters . getissuccessconnect){

  间隙(有效间隔)

  下一个()

  }

  }, 500)

  }

  }

  ]

  })

  控制台打印出下图:

  参考资料:

  1、vue插座。io:https://github.com/MetinSeylan/Vue-Socket.io

  2、socket.io客户端:https://github.com/socketio/socket.io-client

  3.vue-路由器卫士:https://router . vue js . org/zh/guide/advanced/navigation-guards . html

  关于vue-socket.io使用教程详解和踩坑记录的文章到此结束。更多关于vue-socket.io使用教程的信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: