4.21 echarts-Websocket前端代码的改造-组件使用,发送数据给服务器,并接收数据-运行代码, 发现客户端的数据发不出去给服务器-断开重连机制

4.21 echarts-Websocket前端代码的改造-组件使用,发送数据给服务器,并接收数据-运行代码, 发现客户端的数据发不出去给服务器-断开重连机制

一.学习内容

1.1 Websocket前端代码的改造

1.创建 src/utils/socket_service.js 文件,在该文件定义类SocketServie,并定义成单例设计模式

2.定义连接服务器的方法connect,创建WebSocket实例对象

3.监听事件,onopen:连接成功,onclose:连接失败,onmessage:接收数据

4.存储回调函数:registerCallBack(socketType,callBack) { this.callBackMapping[socketType] = callBack}

5.在监听onmessage对接收数据进行处理

  • 对服务器发送的数据反编译转化为对象进行存储

  • 获取前端发送给服务器,回调函数的唯一标识

  • 在callBackMapping对象中通过此标识找到相应的回调函数进行调用,判断回调函数是否存在

  • 判断该回调函数传递的行为,由于当服务器找到接收的action是getData时,它服务器会在接收数据对的基础上增加data字段该字段的值接收客户端需要获取的数据

  • 拿到对象中存储组件获取数据的回调函数,通过call调用该函数,调用对象为ScoketService实例,并传递参数,为数据服务器传递过来的数据。

6.定义发送数据的方法,将该数据发送给服务器,并编译成字符串进行发送

7.挂载SocketServie对象到vue原型身上

import ScoketService from './utlits/scoket_server'
//连接服务器端
SocketService.Instance().connect()
Vue.prototype.$socket=ScoketService.Instance()
export default class ScoketService {
    //单例
    static instance = null
    //创建一个方法用于生成类的实例对象
    static Instance() {
        if (!this.instance) {
            this.instance = new ScoketService()
        }
        return this.instance
    }
    //定义WebSocket实例属性
    ws = null
    //判断是否连接成功
    connected = false
    //延时数据
    secondary = 0
    issuccess = 0
    // 用于存储客户端发送组件函数,用于获取数据的函数
    callBackMapping = {}
    //连接方法
    connect() {
        //判断浏览器是否支持使用WebSocket
        if (!window.WebSocket) {
            return console.log('您的浏览器不支持使用WebSocket')
        }
        //创建WebSocket实例对象
        this.ws = new WebSocket('ws://localhost:9998')
        //监听连接成功
        this.ws.onopen = () => {
            this.connected = true
            this.issuccess = 0
            console.log('服务器连接成功')
        }
        //1.服务器连接不成功 2.服务器关闭了连接
        this.ws.onclose = e => {
            this.connected = false
            this.issuccess++
            setTimeout(() => {
                this.connect()
            }, 500 * this.issuccess)
            console.log('服务器连接失败')
        }
        //监听接收消息
        this.ws.onmessage = msg =>{
            console.log('服务器接收到数据', msg.data)
            //真正服务器发送过来的原始数据在msg的data字段中
            //对服务器发送的数据反编译转化为对象进行存储
            const recvData=JSON.parse(msg.data)
            //获取前端发送给服务器,回调函数的唯一标识
            const socketType = recvData.socketType
            //在callBackMapping对象中通过此标识找到相应的回调函数进行调用
            //判断回调函数是否存在
            if (this.callBackMapping[socketType]) {
                //判断改回调函数传递的行为
                if (recvData.action === 'getData') {
                    //由于当服务器找到接收的action是getData时,它服务器会在接收数据对的基础上增加data字段该字段的值接收客户端需要获取的数据
                    const realData = JSON.parse(recvData.data)
                    //拿到对象中存储组件获取数据的函数,通过call调用该函数,调用对象为ScoketService实例,并传递数据服务器传递过来的数据
                    this.callBackMapping[socketType].call(this,realData)
                }else if(recvData.action==='fullScreen'){

                }else if(recvData.action==='themeChange'){

                }
            }
        }
    }
    //存储回调函数
    registerCallBack(socketType,callBack) {
        this.callBackMapping[socketType] = callBack
    }
    //取消某一个回调函数
    unRegisterCallBack(socketType) {
        this.callBackMapping[socketType] = null
    }
    //定义发送数据的方法,将该数据发送给服务器
    send(data) {
        if (this.connected) {
            this.secondary = 0
            this.ws.send(JSON.stringify(data))
        } else {
            this.secondary++
            setTimeout(() => {
                this.send(data)
            }, 500 * this.secondary)
        }
    }
}

1.2组件使用,发送数据给服务器,并接收数据

1.created 中注册回调函数

created () {
// 当socket来数据的时候, 会调用getData这个函数,参数1:函数的唯一标识,参数2:回调函数
this.$socket.registerCallBack('trendData', this.getData)
}

2.destroyed 中取消注册

destroyed () {
	this.$socket.unRegisterCallBack('trendData')
}

3.mounted 中调用$socket中send发送数据

mounted () {
this.initChart()
    // this.getData() 先将getData的调用注释起来
    this.$socket.send({
    action: 'getData',
        //回调函数的唯一标识
    socketType: 'trendData',
    //告诉服务器哪一个图表数据的获取
    chartName: 'trend'
})
......
},

4.在getData函数中接收数据,实例对象调用该函数,并传递服务器传递过来的数据

getData(res){
//获取数据进行存储
	 this.allData = res;
}

1.3 问题:运行代码, 发现客户端的数据发不出去给服务器

分析:因为在刷新界面之后, 客户端和服务端的连接并不会立马连接成功,需要一段时间进行连接,而 在处于连接状态下就调用

send 是发送不成功的。

解决:需要通过定时器进行异步处理,设置一个属性默认为connected=fasle,通过这个属性在发送数据给服务器之前判断是否连接成功,然后隔一段时间,再次调用send函数进行数据的发送。由于每隔相同的时间进行判断是否连接成功,会有点浪费资源。所以可以设置一个属性变量,每发送一次就加1,在定时器延迟的时间为上一次的时间乘与这个变量,这样可以减少发送的次数提高性能。

// 是否已经连接成功
	connected = false
	sendRetryCount = 0
send (data) {
    console.log('发送数据给服务器:')
    //
    if (this.connected) {
        this.sendRetryCount = 0
        this.ws.send(JSON.stringify(data))
    } else {
    setTimeout(() => {
        this.sendRetryCount++
        this.send(data)
}, 200 * this.sendRetryCount) // 发送数据尝试的次数越大, 则下一次连接的延迟也就越长
}
}

在 onopen 和onclose时设置 connected 的值

connect () {
......
this.ws.onopen = () => {
console.log('WebSocket 连接成功')
this.connected = true
}
  this.ws.onclose=e=>{
      this.connected=false
      ................
      }

1.4 断开重连机制

问题:如果初始化连接服务端不成功, 或者连接成功了, 后来服务器关闭了, 这两种情况都会触发 onclose 事件,

我们需要在这个事件中,进行重连.

思路:利用定时器进行延迟调用服务器连接机制,并设置重连次数, 重连次数越大, 下一次再发起重连的延时也就越长,提高性能。

connectRetryCount = 0 // 重连次数, 重连次数越大, 下一次再发起重连的延时也就越长
connect () {
this.ws.onopen = () => {
......
	this.connectRetryCount = 0 // 连接成功之后, 重置重连次数
}
......
// 1.服务器连接不成功 2.服务器关闭了连接
    this.ws.onclose = e => {
    console.log('服务器关闭了连接')
    setTimeout(() => {
    	this.connectRetryCount++
    this.connect()
}, 200 * this.connectRetryCount)
}
}

二.问题及解决

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值