当前位置: 首页 > 知识库问答 >
问题:

前端 - 在vue项目中,使用websocket方式来获取服务端的数据,运行报错?

蒋星雨
2023-05-15

报错:

app.js:2570 Uncaught TypeError: Cannot read properties of null (reading 'connect')

main.js代码:

import SocketService from '@/utils/socket_service.js'
SocketService.instance.connect()
Vue.prototype.$socket = SocketService.instance

封装好的socket_service.js代码:

export default class SocketService {
  /**
   * 单例
   */
  // 定义一个属性为空
  static instance = null
  // 定义一个静态方法
  static get Instance () {
    if (!this.instance) {
      this.instance = new SocketService()
    }
    return this.instance
  }

  // 和服务端连接的socket对象
  ws = null

  // SocketService的实例属性,同时是个对象,用来存储每一个回调函数,,,数据组织形式是key(socketType)和value(xxdata)
  callBackMapping = {}

  // 标识是否连接成功
  connected = false

  // 记录重试的次数
  sendRetryCount = 0

  // 重新连接尝试的次数
  connectRetryCount = 0

  //  定义连接服务器的方法
  connect () {
    // 连接服务器
    if (!window.WebSocket) {
      return console.log('您的浏览器不支持WebSocket')
    }
    // 1.创建前端websocket对象
    this.ws = new WebSocket('ws://localhost:9998')

    // 2.1连接成功的事件
    this.ws.onopen = () => {
      console.log('连接服务端成功了')
      // this.connected = true
      // 重置重新连接的次数
      // this.connectRetryCount = 0
    }
    // 2.2连接服务端失败
    // 2.2.1当连接成功之后, 服务器关闭的情况
    this.ws.onclose = () => {
      console.log('连接服务端失败')
      // this.connected = false
      // this.connectRetryCount++
      // setTimeout(() => {
      //   this.connect()
      // }, 500 * this.connectRetryCount)
    }
    // 2.3得到服务端发送过来的数据
    this.ws.onmessage = msg => {
      console.log('从服务端获取到了数据')
      // 真正服务端发送过来的原始数据时在msg中的data字段
      // console.log(msg.data)
      const recvData = JSON.parse(msg.data)
      const socketType = recvData.socketType
      // 判断回调函数是否存在
      if (this.callBackMapping[socketType]) {
        const action = recvData.action
        if (action === 'getData') {
          const realData = JSON.parse(recvData.data)
          this.callBackMapping[socketType].call(this, realData)
        } else if (action === 'fullScreen') {
          this.callBackMapping[socketType].call(this, recvData)
        } else if (action === 'themeChange') {
          this.callBackMapping[socketType].call(this, recvData)
        }
      }
    }
  }

  // 回调函数的注册,,,其实是callbackMapping的父构造函数
  registerCallBack (socketType, callBack) {
    this.callBackMapping[socketType] = callBack
  }

  // 取消某一个回调函数
  unRegisterCallBack (socketType) {
    this.callBackMapping[socketType] = null
  }

  // 发送数据的方法
  // send (data) {
  //   // 判断此时此刻有没有连接成功
  //   if (this.connected) {
  //     this.sendRetryCount = 0
  //     this.ws.send(JSON.stringify(data))
  //   } else {
  //     this.sendRetryCount++
  //     setTimeout(() => {
  //       this.send(data)
  //     }, this.sendRetryCount * 500)
  //   }
  // }
}

共有2个答案

江鹏飞
2023-05-15

你的单词拼错了: image.png

或者直接new SocketService().connect() 也可以, 也不用定义静态的get

淳于熙云
2023-05-15

你封装的SocketService是一个类。你要使用应该先new一个其实例出来

import SocketService from '@/utils/socket_service.js'
new SocketService().connect()
 类似资料: