Vue中 引入使用 vue-socket.io,以及vue真实项目上使用

socket 网址:英文官网

一、 WebSocket 简介

前端和后端的交互模式最常见的就是:前端发数据请求,从后端拿到数据后展示到页面中。
如果前端不做操作,后端不能主动向前端推送数据,这也是http协议的缺陷。
一种新的通信协议应运而生 WebSocket,它最大的特点就是服务端可以主动向客户端推送消息,客户端也可以主动向服务端发送消息,实现了真正的平等。

WebSocket 其他特点:

  • 建立在 TCP 协议之上,服务器端的实现比较容易;
  • 与 HTTP 协议有着良好的兼容性;
  • 默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
  • 数据格式比较轻量,性能开销小,通信高效;
  • 可以发送文本,也可以发送二进制数据;
  • 没有同源限制,客户端可以与任意服务器通信;
  • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL;

二、vue中使用websocket

  1. 安装及引入
    vue-socket.io 其实是在 socket.io-client(在浏览器和服务器之间实现实时、双向和基于事件的通信) 基础上做了一层封装,将 $socket 挂载到 vue 实例上,同时可使用 sockets 对象轻松实现组件化的事件监听,在 vue 项目中使用起来更方便。

安装:

npm i vue-socket.io

引入:

// main.js
import Vue from 'vue'
import store from './store'
import App from './App.vue'
import VueSocketIO from 'vue-socket.io'

Vue.use(
  new VueSocketIO({
    
    
    // 生产环境建议关闭,开发环境打开(在控制台看到socket连接和事件监听的信息)
    debug: true, 
    connection:'http://metinseylan.com:1992',
    options:{
    
    
      // 创建时是否自动连接 我们这里设定为false,在指定页面再开启
      autoConnect: false,
      // 路径(默认值:/socket.io/) 
      path: "/my-app/",
      // 目前有两种传输方式:HTTP long-polling(可简称:polling)、WebSocket
      transports: ['polling'],
      // 附加请求头(在服务器端的 socket.handshake.headers 对象中找到)
      extraHeaders:{
    
    },
    },
    // 如果没有使用到 store 可不写
    vuex: {
    
    
      store,
      actionPrefix: 'SOCKET_',// vuex action 前缀
      mutationPrefix: 'SOCKET_', // vuex mutation 前缀
    },
  })
)

new Vue({
    
    
  router,
  store,
  render: h => h(App)
}).$mount('#app')

在这里插入图片描述
组件内使用:

<template>
  <div class="wrap">
    <button @click="socketEmit">连接Socket</button>
    <button @click="socketSendmsg">发送数据</button>
  </div>
</template>

<script>
export default {
    
    
  data(){
    
    
    return {
    
    
      randomId:null,
    }
  },
  methods:{
    
    
    socketEmit(){
    
    
      // 开始连接 socket
      this.$socket.open();
      // 订阅事件,testCall 是与后端约定好的名称
      this.sockets.subscribe('testCall', (res) => {
    
    
        if(res.code == 200 && res.randomId === this.randomId){
    
    
          console.log('召唤成功')

        }
      })
    },
    // 发送消息
    socketSendmsg(){
    
    
      this.randomId = Math.random();
      // testCall 是与后端约定好的名称
      this.$socket.emit('testCall', {
    
     
        "randomId": this.randomId,
        "deviceId": "123456"
      });
    },
  },
  sockets: {
    
    
    connect: function () {
    
    
      console.log('连接成功')
    },
    disconnect: function () {
    
    
      console.log('断开连接')
    },
    reconnect: function () {
    
    
      console.log('重新连接')
    },
  },
  beforeDestroy(){
    
    
    // 关闭 Socket
    this.sockets.unsubscribe('testCall'); 
    this.$socket.close();
  },
}
</script>

三、vue真实项目使用(vue+ts)

1)安装:npm i vue-socket.io
2)新建socket.ts文件,与app.vue文件同级;

/**
 * ! socket在全部环境下使用,但仅在开发环境会在控制台抛出错误日志信息
 * 这个项目因为有用户权限管理,所以给后台发送token验证通过后,才后走通socket。如果项目不需要,直接在
 */

import store from './store'

import VueSocketIO from 'vue-socket.io' // vue-socketio
import SocketIO from 'socket.io-client' // socketio
import Cookies from 'js-cookie'

// 正常项目,这里要再加一个token的参数;因为当前项目有权限管理,需要发送token给后端验证通过,所以token做了发送事件:socketInstance.emit('register', Cookies.get('yi-token'))
  })
const socketInstance = SocketIO(process.env.VUE_APP_BASE_WS as string, {
    
    
  reconnectionAttempts: 5,
  timeout: 5000
})

// 开发环境做了打印配置;
if (process.env.NODE_ENV === 'development') {
    
    
  socketInstance.on('connect_error', () => {
    
    
    console.log('%cSocket:', 'color:#EA3D2F;font-weight:500', 'Websocket init failed')
  })
  socketInstance.on('connect', () => {
    
    
    console.log('%cSocket:', 'color:#00B69B;font-weight:500', 'Websocket init succeed')
    // 发送事件,入参token
    socketInstance.emit('register', Cookies.get('yi-token'))
  })
} else {
    
    
  // 线上
  // 此处发送了事件token给后端,后端验证用户信息;此项目的特殊处理
  socketInstance.on('connect', () => {
    
    
    socketInstance.emit('register', Cookies.get('yi-token'))
  })
}
  //  实例化一个VueSocketIO
const VueSocketIOInstance = new VueSocketIO({
    
    
  debug: process.env.NODE_ENV === 'development',
  connection: socketInstance,
  vuex: {
    
    
    store,
    actionPrefix: 'SOCKET_',
    mutationPrefix: 'SOCKET_'
  }
})

export default VueSocketIOInstance

vuex做了如下配置store/task,js

export default {
    
    
  namespaced: true,
  state: {
    
    
    noticeCount: 0,
    licenseUpdate: 0
    // taskProcess:{},
  },
  mutations: {
    
    
    // 需要使用 SOCKET_, vuex mutation 前缀
    // 消息提示(数字)
    SOCKET_notice_count(state, data) {
    
    
      state.noticeCount = data
    },
    // 漏洞库管理已过期
    SOCKET_license_update(state, data) {
    
    
      state.licenseUpdate = data
    }
  },
  actions: {
    
    },
}

封装了一个socket.vue文件,放在sidebar中,登录页面进来直接调用;

socket.vue文件

<template>
  <div />
</template>

<script lang="ts">
import Vue from 'vue'
/**
 * websocket 组件,写 tmplate 仅仅为了让 vue 不报错
 */
export default Vue.extend({
    
    
  name: 'SocketComponent',
  sockets: {
    
    
    // 获取socket推送消息提示
    notice_count() {
    
    
      // console.log('socket组件中 noticce_count', data)
    }
  }
})
</script>

sidebar.vue文件:

<template>
  //  使用socket
  <Socket />  
</template>

以上配置完成后,页面中开始使用:
业务逻辑页面: popbox.vue, 监听$store.state.task.noticeCount.count’即可,有数据直接显示;

  watch: {
    
    
    '$store.state.task.noticeCount.count': {
    
    
      handler: function (val) {
    
    
        if (val > 0) {
    
    
          localStorage.removeItem('NOTICE_COUNT_FROMLOGIN')
          this.total = val
        }
      },
      deep: true
    },

业务逻辑页面:system.vue: 监听前后数据是够一致,不一致调用接口更新提示语;

watch: {
    
    
 '$store.state.task.licenseUpdate.count': {
    
    
      handler: function (newval, oldval) {
    
    
        if (oldval !== newval) {
    
    
          this.freshLicenseInfoEvent(true)
        }
      },
      deep: true
    }

}

业务逻辑页面,根据具体需求,具体来实现。

参考:https://blog.csdn.net/ZYS10000/article/details/122737466

参考文章: https://blog.csdn.net/ZYS10000/article/details/113056868

猜你喜欢

转载自blog.csdn.net/weixin_44834981/article/details/126915814