Vue项目中使用WebSocket(实现视频计时)

842 阅读5分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

简介

学习之前我们首先应该带着几个疑惑去学习。websocket是什么?有什么作用?以及在项目中如何使用?

一.WebSocket是什么

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。(说白了就是一个通信协议)

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二.WebSocket优点

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

三.WebSocket使用

上面说了一些WebSocket的优点,这里我们就来讲一下如何使用。

WebSocket的使用特别简单只需要:const Socket = new WebSocket(url,[protocol])

这里的url我们就不能像平时写的Http一样,我们需要将协议变为 ws。如下所示

const Socket = new WebSocket("ws://localhost:8080/main")(这里就是在建立连接)

而第二个参数是可选的,指定可接受的子协议。这里我们不做过多介绍(因为我也不会,有知道的小伙伴可以科普一下)

当我们连接地址成功后,就可以触发一些WebSocket中的函数与方法,方便我们操作。下面就介绍一下具有的事件和方法(在开发中离不开下面的事件和方法)。

四.WebSocket的事件

事件事件处理程序描述
openSocket.onopen连接建立时触发
messageSocket.onmessage客户端接收服务端数据时触发
errorSocket.onerror通信发生错误时触发
closeSocket.onclose连接关闭时触发

五.WebSocket 方法

方法描述
Socket.send()使用连接发送数据
Socket.close()关闭连接

六.小试牛刀(Vue2 聊天室(极简版))

GitHub项目地址是:github.com/zhaoyanjiao…

在这里我们只展示一些 前端代码,想看完整项目可以去GitHub中下载,里面存在node写的后端运行起来就可以使用。(记得点个Star)

第一步:首先我们是需要建立连接:

// 使用websocket
const ws = new WebSocket('ws://localhost:8000')

第二步:在生命周期函数中去监听websocket事件

mounted() {
  ws.addEventListener('open', this.handleWsopen, false)
  ws.addEventListener('close', this.handleWsclose, false)
  ws.addEventListener('error', this.handleWserror, false)
  ws.addEventListener('message', this.handleWsmessage, false)
},

第三步:实现对应的事件函数(重点是 handleWsmessage 函数这里可以拿到后端传递过来的数据)

//这是ws中的4个事件
handleWsopen(e) {
  console.log('open-建立了连接', e)
},
handleWsclose(e) {
  console.log('close-关闭了连接', e)
},
handleWserror(e) {
  console.log('error-连接错误', e)
},
//这里就可以接收后端广播出来的信息
handleWsmessage(e) {
  this.dataList.push(JSON.parse(e.data))
},

第四步:前端将数据传递给后端

//这里是将前端数据发送给后端
ws.send(JSON.stringify({
  value: this.value,
  id: new Date().getTime(),
  dateTime: new Date().getTime(),
  name: localStorage.getItem('name')
}))

上面大概就是我们的逻辑代码,下面是整个页面的代码(可以参考一下)

<template>
  <div class="home">
    <ul>
      <li v-for="item in dataList">
        <span>{{item.name}}</span>
        <span>{{item.id}}</span>
        <span>{{item.dateTime}}</span>
        <p>消息:{{item.value}}</p>
      </li>
    </ul>
    <input type="text" v-model="value">
    <button @click="handleWssend">发送</button>
  </div>
</template>

<script>
  // 使用websocket,前端就要挂载 ws的4个方法   (_在这里写的ws代码 都可以封装出来)
  const ws = new WebSocket('ws://localhost:8000')

  export default {
    name: 'Home',
    data() {
      return {
        value: '',
        dataList: []
      }
    },
    mounted() {
      ws.addEventListener('open', this.handleWsopen, false)
      ws.addEventListener('close', this.handleWsclose, false)
      ws.addEventListener('error', this.handleWserror, false)
      ws.addEventListener('message', this.handleWsmessage, false)
    },
    methods: {
      handleWssend() {
        let newvalue = this.value
        if (!newvalue.trim().length) return

        //这里是将前端数据发送给后端
        ws.send(JSON.stringify({
          value: this.value,
          id: new Date().getTime(),
          dateTime: new Date().getTime(),
          name: localStorage.getItem('name')
        }))
        this.value = ''
      },
      //这是ws中的4个事件
      handleWsopen(e) {
        console.log('open-建立了连接', e)
      },
      handleWsclose(e) {
        console.log('close-关闭了连接', e)
      },
      handleWserror(e) {
        console.log('error-连接错误', e)
      },
      //这里就可以接收后端广播出来的信息
      handleWsmessage(e) {
        this.dataList.push(JSON.parse(e.data))
      },
    }
  }
</script>

七.项目中实现的视频计时功能(仅前端代码)

前奏:封装视频通用地址

仅提供一下思路,代码并不通用

//根据http协议判断是否为ws或wss
let proto = document.location.protocol == "http:" ? "ws:" : "wss:";
//取地址+端口,配置80端口时port是空的,所以判断一下
let address = document.location.port ?
    document.location.hostname + ":" + document.location.port :
    document.location.hostname;
//拼接请求地址
export default {
  videoTimeUrl: proto + address + "/ws/train/",
}

第一步:建立连接

在这里我们就需要考虑的周全一些,判断打开视频的浏览器是否支持Websocket连接。这里连接的this.wsurl就需要你们根据 前奏+后端 给的地址拼接出来。才可以正确的建立连接

//建立ws连接
createWebSocket() {
  let newws = null //创建变量 为了在函数中更方便的使用实例
  if ("WebSocket" in window) { //判断当前浏览器是否支持 ws
    newws = new WebSocket(this.wsurl) //使用websocket
    this.ws = newws//将实例化对象 赋值给变量方便使用
  } else if ("MozWebSocket" in window) {
    newws = new MozWebSocket(this.wsurl);
    this.ws = newws//将实例化对象 赋值给变量方便使用
  } else {
    this.err('请换个浏览器观看视频')
    return
  }
  //接收后端传递的信息
  newws.onmessage = e => {
    if (e.data == 'ok') return
  }
  //关闭连接
  newws.onclose = e => {
  }
  //打开连接
  newws.onopen = e => {
  }
  //连接错误
  newws.onerror = e => {
    this.err('计时失败,请刷新后重新观看')
  }
}

第二步:控制什么时候开始计时操作

我们的计时操作就是需要在视频开始播放时进行。在这里实现视频播放使用的一个插件vue-video-player。插件里面有视频播放时触发的函数,我们只需要在视频播放时,开始建立WebSocket连接即可。参考代码:

//点击视频播放时
onPlayerPlay() {
  this.createWebSocket() //在播放视频时建立连接
},

第三步:当用户点击了视频暂停

当用户点击了视频暂停时,我们就需要把WebSocket连接断开,这样就暂停了计时。插件里面也有视频暂停时触发的函数,我们在函数中做操作即可。参考代码:

//视频暂停时
onPlayerPause() {
  this.ws.close()//关闭连接
},

以上的步骤就可以实现简单的视频计时功能(当然还是离不开后端的支持),做的还是比较简陋,但是实现了我们的需求。

总结

以上就是我学习WebSocket和使用的过程,写的不好的地方,欢迎指出。如果对你有帮助,记得点赞👍