vue中使用websocket实践

17 篇文章 0 订阅

问题描述:最近有项目涉及到前后端websocket通信,在封装好了websocket相关的方法后,需要在onmessage里面拿到后端的返回信息。也看了网上很多实例,大部分都是直接在.vue文件里面去初始化websocket,考虑到自己项目的实际情况决定将websocket的一些方法抽离出来,方便复用。这里记录一下onmessage事件的处理

import { websocketConfig } from '../config'
let ws = null;
let heartBeatTimer = null;

/** 建立websocket连接*/
const handleCreateWS = () => {
  //...省略一些代码
  ws.onmessage = websocketOnmessage
  //...省略一些代码
}

//...省略一些代码

/** 数据接收处理*/
const websocketOnmessage = (e) => {
  let customEvent = new CustomEvent('onmessageWS', {
    detail: {
      data: e.data
    },
    bubbles: false, //该事件是否冒泡
    cancelable: false, //该事件能否被取消
    composed: false //指示事件是否会在影子DOM根节点之外触发侦听器。
  })
  if (window.dispatchEvent) {
    window.dispatchEvent(customEvent);
  } else {
    window.fireEvent(customEvent);
  }
}

export default {handleCreateWS  //...省略一些希望暴露出去的api方法 }

上面的代码是封装的方法,因为将websocket逻辑部分做了抽离,所以处理事件接收就需要动一动脑筋。开始是打算直接在websocketOnmessage方法中通过区分data的信息去调用不同的事件。后来考虑到消息的多样性,后期肯定会有代码臃肿难维护的问题。所以为了将不同的消息放在各自的组件中处理,最终考虑使用自定义事件的方法,将事件挂载到window上,在页面中使用只需要监听事件,拿到对应的数据再经行处理就ok了

<template>
	<div>组件</div>
</template>

<script>
  import scoket from '@/utils/websocket'
  export default {
    created() {
      scoket.handleCreateWS()
    },
    mounted() {
      window.addEventListener('onmessageWS', this.handleMessage() })
    },
    destroyed() {
      window.removeEventListener('onmessageWS'})
    },
    methods: {
      handleMessage(e) {
        console.log('监听到了')
        console.log('---------------')
        console.log(e)
        console.log('---------------')
      }
    }
  }
</script>

<style lang="less" scoped>

</style>

依照以往监听滚动,监听resize的经验,写到这里,一切都感觉很OK。兴奋的跑一跑代码,问题出现了。页面中拿不到onmessage的消息,打印结果是undefined。找了好久的问题,也查看了很多的文章,几乎没有找到相关的问题。难受!

在这里插入图片描述

经过不懈努力,终于找到了问题所在,问题出在this指向。

mounted() {
	  //报错的写法,这里的this指向的是window
	  window.addEventListener('onmessageWS', this.handleMessage(), false) 
      //修改之后的写法,用箭头函数承接一下,this指向vue实例
      window.addEventListener('onmessageWS', (e) => { this.handleMessage(e), false })
    },

在这里插入图片描述

不知道是不是vue对监听其他的浏览器事件进行过处理。在本次实践中自定义事件使用常规的写法不能直接使用this来使用methods里面的方法。这也是因为自己的常规思维导致的错误。记录一下,希望以后能避免采坑。

---------------------------------------------补充问题------------------------------------------------

如何在websocket里面传递参数?后台为了保证连接的安全性,要求在连接websocket的时候加入token,比较可靠的解决方法目前有两种:

  • websocket请求头中可以包含Sec-WebSocket-Protocol这个属性,该属性是一个自定义的子协议。它从客户端发送到服务器并返回从服务器到客户端确认子协议。我们可以利用这个属性添加token。这种实现方式需要后端处理一下他们的代码!
  • 直接在请求接口里面添加token参数
let { wsUri, token = '12345678' } = websocketConfig;
  ws = new WebSocket(wsUri, token);
let { wsUri } = websocketConfig;
new WebSocket(`${wsUri }?token='xxxxx'`)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值