电商数据可视化实时监控系统(二)

本文主要介绍了WebSocket在电商数据可视化实时监控系统中的使用,通过WebSocket实现服务器主动向客户端推送信息,以增强系统的实时性。内容包括WebSocket的安装和使用,以及系统中三个关键板块:地区销售排行、热销商品占比和库存销量分析的分解介绍。
摘要由CSDN通过智能技术生成

一、补充知识点

websocket

websocket实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
而HTTP 协议通信只能由客户端发起,HTTP 协议做不到服务器主动向客户端推送信息

npm i ws -S

后端:

1、创建web_socket_service.js文件
    在 app.js 文件中:
    // 引入WebSocket
    const webSocketService = require('./service/web_socket_service')
    webSocketService.listen() // 开启监听
    
    在 web_socket_service.js 中:
        const WebSocket = require('ws')
    const path = require('path')
    const {
   
      getFileJsonData
    }     = require('../utils/file_utils')

    // 1、创建WebSocket服务端对象,绑定端口
    // const WebSocket = require('ws')
    const ws = new WebSocket.Server({
   
      port: 9998,
    }, () => {
   
      console.log('websocket is listening port: 9998');
    })
    module.exports.listen = () => {
   
      // 2、对客户端连接事件进行监听,client是客户端的socket连接对象
      ws.on('connection', (client) => {
   
        console.log('client connected successfully, total client:' + ws.clients.size);
        // 3、对客户端的连接对象进行message事件监听,msg由客户端发送给服务端的数据
        client.on('message', async (msg) => {
   
          const payload = JSON.parse(msg)
2、服务端接收数据字段约定 
3、服务端发送数据字段约定         
          const action = payload.action
          if (action === 'getData') {
    // 取出图表名,然后获取数据,再添加data字段给前端
            // payload.chartName取出数据中心的chartName字段       
            filePath = `../data/${
     payload.chartName}.json`
            // fullPath拼接json文件的路径
            let fullPath = path.join(__dirname, filePath) // 保证动态的绝对路径
            // 保证后台不崩溃,就需要用try-catch
            try {
   
              // getFileJsonData读取该文件的内容
              let data = await getFileJsonData(fullPath)
              // 需要在服务端获取到数据的基础之上,增加一个data的字段
              // data所对应的值,就是某个json文件的内容
              payload.data = data
              client.send(JSON.stringify(payload))
    
            } catch (error) {
   
              payload.data = null
              client.send(JSON.stringify(payload))
            }
          } else {
    // 不是获取数据,直接原封不动地发给每个客户端
            // clients所有客户端的连接,效果就是假如说1号全屏开启,那么2号和3号就会自动全屏显示效果    
            ws.clients.forEach(item => {
   
              item.send(msg)
            })
          }
        })
      })
    }

前端:

1、创建socketUtils.js文件
  在main.js中:
  import SocketService from '@/utils/socketUtils'
  SocketService.Instance.connect() // 创建实例并连接服务器
  // 挂载到Vue原型身上,方便用this.$socket 
  Vue.prototype.$socket = SocketService.Instance 

  在socketUtils.js文件中:
   export default class SocketService {
   
     // 单例设计模式
     static instance = null
     // 在Instance方法中先判断this.instance是否存在
     static get Instance() {
   
       if (!this.instance) {
   
         this.instance = new SocketService()
       }
       return this.instance
        }
     ws = null
     callBackMapping = {
   } // 存储回调函数
   
     hasConnected = false // 标识是否连接成功
     sendRetryTimes = 0 //记录失败次数
     connectRetryTimes = 0
   
     // connect定义连接服务器的方法
     connect() {
   
       // 判断浏览器是否支持WebSocket
       if (!window.WebSocket) {
   
         return window.alert('您的浏览器不支持WebSocket。')
       }
       this.ws = new window.WebSocket('ws://localhost:9998')
       this.ws.onopen = () => {
    // 监听一些事件
         console.log('connected server successfully');
         this.hasConnected = true
         this.connectRetryTimes = 0
       }
       this.ws.onclose = () => {
   
         console.log('connected server failed');
         this.hasConnected = false
         this.connectRetryTimes++
         window.setTimeout(() => {
   
           this.connect()
         }, 500 * this.connectRetryTimes)
       }
       //得到服务端发送过来的数据
       this.ws.onmessage = (msg) => {
    // 监听服务端发送消息
         const data = JSON.parse(msg.data)
         const socketType = data.socketType //得到回调函数的标识
         // 判断回调函数是否存在
         if (this.callBackMapping[socketType]) {
   
           const action = data.action
           if (action === 'getData') {
   
             const chartData = JSON.parse(data.data)
             // console.log('前端收到数据:', data.data);
             this.callBackMapping[socketType].call(this, chartData)
           } else if (action === 'fullScreen') {
   
             this.callBackMapping[socketType].call(this, data)
           } else if (action === 'themeChange') {
   
             this.callBackMapping[socketType].call(this, data)
           }
         }
    }
     }
     // 因为下面几个方法是在vue组件里调用的,因此挂载到vue原型上比较方便
    registerCallBack(socketType, callback) {
    // 回调函数注册,以socketType为key
       this.callBackMapping[socketType] = callback
     }
   
     unregisterCallBack(socketType) {
    // 注销回调函数
       this.callBackMapping[socketType] = null
     }
     // 发送数据的方法
     send(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值