后端和 前端入口 准备工作都做完了 接下来就是各个图表组件内部的 逐个修改
各个图表组件修改
- 进入组件时 this.$socket.registerCallBack注册函数 (可选:trendData,sellerData,mapData,rankData,hotData,stockData) 然后传入自己getData函数
- 组件挂载到页面上时并 初始化图表之后 调用 this.$socket.send 方法发送数据
- 组件注销时 卸载 进入组件时注册的函数
- getData的修改 改为不由自己调用 服务器返回数据时 自行调用
created() {
// 注册webSocket 函数
this.$socket.registerCallBack('rankData',this.getData)
},
mounted() {
// 渲染DOM元素之后 初始化图表实例 请求数据 监听页面尺寸变化
this.initChart()
// 注释掉直接发送请求数据
//this.getData()
// 通过 send 方法 向服务器发送数据
this.$socket.send({
action:'getData',
socketType: 'rankData',
chartName: 'rank',
value:''
})
window.addEventListener('resize',this.screenAdapter)
this.screenAdapter()
},
// 销毁组件时 注销 webSocket 函数
destroyed() {
clearInterval(this.timerID)
window.removeEventListener('resize',this.screenAdapter)
this.$socket.unRegisterCallBack('rankData')
},
methods:{
getData(res){
//const {data:res} = await this.$http.get('rank')
this.allData = res
this.allData.sort((a,b) =>{
return b.value - a.value // 从大到小排序
})
this.updateChart()
this.startInterval()
},
}
逻辑流程梳理
准备工作
上篇文章已经讲解(后端创建 service/web_socket_service.js)app.js引用
前端 src/utils/socket_service.js 并在main.js 引入 挂载到Vue原型上 this.$socket
一、进入组件时挂载 函数
Rank.vue:
created() {
// 注册webSocket 函数
this.$socket.registerCallBack('rankData',this.getData)
},
src/utils/socket_service.js
在callBackMapping对象中 注册一个函数 名字为 第一个参数 内容为第二个参数
registerCallBack(socketType,callBack){ this.callBackMapping[socketType] = callBack }
二、组件挂载到DOM上时 使用 this.$scoket.send 方法
mounted() {
// 通过 send 方法 向服务器发送数据
this.$socket.send({
action:'getData',
socketType: 'rankData',
chartName: 'rank',
value:''
})
}
src/utils/socket_service.js
// 发送数据的方法 send(data){ // 判断此时此刻有没有连接成功 不成功就一段时间后(越来越久)再次发送 if (this.connected){ this.sendRetryCount = 0 this.ws.send(JSON.stringify(data)) }else { this.sendRetryCount++ setTimeout(() =>{ this.send(data) },500 * this.sendRetryCount) } }
后端 service/web_socket_service.js 接收到前端发送数据时的响应:
判断action是不是 getData 是的话就根据 chartName 拼接路径 查找数据 赋值给新增的data 属性
不是getDta 的话就原封不动的将数据转发给每一个处于链接状态的客户端 根据value 变更主图或者 全屏切换 wss.clients 所有客户端的链接
// 对客户端的连接对象进行message 事件监听
// msg:由客户端发给服务器的数据
client.on('message',async msg => {
console.log('客户端发送数据给服务端了:' + msg)
let payload = JSON.parse(msg)
const action = payload.action
if (action === 'getData'){
let filePath = '../data/' + payload.chartName + '.json'
// payload.chartName 六选一 trend seller map rank hot stock
filePath = path.join(__dirname,filePath)
const ret = await fileUtils.getFileJsonData(filePath)
// 根据路径找到 json 数据 传出去
payload.data = ret
client.send(JSON.stringify(payload))
}else {
// 不是getDta 的话就原封不动的将数据转发给每一个处于链接状态的客户端 根据value 变更主图或者 全屏切换 wss.clients 所有客户端的链接
wss.clients.forEach(client => {
client.send(msg)
})
}
// 由服务器往客户端发送数据
//client.send('hello socket from 后端')
})
发送给前端 前端(src/utils/socket_service.js)监听到发送过来的数据
判断action 类型 调用created 创建的函数 传参 就运行了 getData
如果是主题切换 或者全屏切换 事件就传入其他参数 不需要data
// 得到服务器发送过来的数据
this.ws.onmessage = msg => {
console.log('从服务器获取到了数据')
// 真正的服务端发送过来的原始数据在msg中的data字段
//console.log(msg.data)
const recData = JSON.parse(msg.data)
const socketType = recData.socketType
// 判断回调函数是否存在
if(this.callBackMapping[socketType]){
const action = recData.action
if (action === 'getData'){
const realData = JSON.parse(recData.data)
// 在这里才是真正的调用+传参
// 不用 .call(this,realData) 没有影响 还是他们的this 指向同一个对象
this.callBackMapping[socketType](realData)
}else if (action === 'fullScreen'){
this.callBackMapping[socketType](recData)
}else if (action === 'themeChange'){
this.callBackMapping[socketType](recData)
}
}
}