美文网首页
vue websocket 连接实战及遇到的问题

vue websocket 连接实战及遇到的问题

作者: 路过的人儿 | 来源:发表于2019-03-07 18:28 被阅读0次

常规的连接方法

websocket () {
     let ws = new WebSocket('ws://localhost:8080')
     ws.onopen = () => {
        // Web Socket 已连接上,使用 send() 方法发送数据
          ws.send('Holle')
          console.log('数据发送中...')
      }
      ws.onmessage = evt => {
        // console.log('数据已接收...')
      }
      ws.onclose = function () {
        // 关闭 websocket
        console.log('连接已关闭...')
      }
      // 路由跳转时结束websocket链接
      this.$router.afterEach(function () {
        ws.close()
      })
}

根据上面的方法名字可以知道,上面的函数都是,相对应的回调函数,比如,omopen指的就是连接成功后的回调

具体项目中的完整方法代码

server.js 是请求接口的封装,先实例化了一个websocket的请求,我把websocket的请求封装成了一个公共方法,放在request.js

import request from './request'
import { wsUrl } from '../../../config'
const ws = new WebSocket(wsUrl)
export default {
  list (cb) {
    let attr = {
      'obj': 'homeMenu',
      'act': 'list'
    }
    request.requestData(ws, attr, cb)
  },
  homeArticleList (page = 1, limit = '10', cb) {
    let attr = {
      'obj': 'homeArticle',
      'act': 'list',
      'page': page,
      'limit': limit
    }
    request.requestData(ws, attr, cb)
  },
  articleByMenuId (id, page = 1, limit = '10', cb) {
    let attr = {
      'obj': 'articleByMenuId',
      'act': 'list',
      'menuId': id,
      'page': page,
      'limit': limit
    }
    request.requestData(ws, attr, cb)
  },
  articleInfoByMenuId (id, cb) {
    let attr = {
      'obj': 'articleByMenuId',
      'act': 'info',
      'menuId': id
    }
    request.requestData(ws, attr, cb)
  },
  article (id, cb) {
    let attr = {
      'obj': 'article',
      'act': 'get',
      'articleId': id
    }
    request.requestData(ws, attr, cb)
  },
  websocket (cb) {
    let attr = {
      'obj': 'homeMenu',
      'act': 'list'
    }
    request.requestData(ws, attr, cb)
  }
}

request.js

window.apiCallback = []
let requestData = (ws, attr, cb) => {
  init(ws)
  window.console.info('send:', JSON.stringify(attr))
  // 发送信息
  window.apiCallback[attr.obj + '_' + attr.act] = function (data) {
    if (data.ustr) {
      alert(data.ustr)
    } else if (cb) {
      cb(data)
    }
  }
  if (ws.readyState === 1) {
    let sendStr = JSON.stringify(attr) + '\n'
    ws.send(sendStr)
  }
  ws.addEventListener('open', function () {
    let sendStr = JSON.stringify(attr) + '\n'
    ws.send(sendStr)
  })
}
function init (ws) {
  ws.onmessage = evt => {
    console.log('数据已接收...')
    let parseData = evt.data.replace(/[\s\r\n]+$/, '').split('\n')
    parseData.splice(0, 1)
    parseData = JSON.parse('[' + parseData.join(',') + ']')
    let key = parseData[0].obj + '_' + parseData[0].act
    if (window.apiCallback[key]) {
      window.apiCallback[key](parseData[0])
    }
  }
  ws.onclose = function () {
    // 关闭 websocket
    console.log('连接已关闭...')
  }
}

let close = (ws) => {
  ws.close()
}

export default {
  requestData,
  close
}

上方有一处关键的地方:

// 判断websocket的连接状态,当未 1 时,证明连接成功,方可发起请求
if (ws.readyState === 1) {
    let sendStr = JSON.stringify(attr) + '\n'
    ws.send(sendStr)
}
//  首次页面加载的时候,则需要监听websoket的状态是不是处于open状态
ws.addEventListener('open', function () {
    let sendStr = JSON.stringify(attr) + '\n'
    ws.send(sendStr)
})

上面的问题如果不做处理则会出现下图的报错


image.png

通常在实例化一个websocket对象之后,客户端就会与服务器进行连接。但是连接的状态是不确定的,于是用readyState属性来进行标识。它有四个值,分别对应不同的状态:

  • CONNECTING:值为0,表示正在连接;
  • OPEN:值为1,表示连接成功,可以通信了;
  • CLOSING:值为2,表示连接正在关闭;
  • CLOSED:值为3,表示连接已经关闭,或*者打开连接失败。

相关文章

网友评论

      本文标题:vue websocket 连接实战及遇到的问题

      本文链接:https://www.haomeiwen.com/subject/asehpqtx.html