The requirements phase

Recently, I met a requirement — “Real-time display of the running status of background server and network equipment on the page”.

Technology selection

If the whole project is based on Vue chart I use Echarts library for real-time update? So what technology are we going to use? The life cycle of Http is defined by Request, that is, Request a Response, the client sends a Request, the server responds to the Request, the server cannot actively send a Request to the client, and the connection is transient. So this is where Websocket comes in

What is the Websocket

WebSocket is an application layer protocol based on TCP and is used to achieve bidirectional communication in C/S architecture applications. Although WebSocket uses HTTP to establish connections, this does not mean that WebSocket is implemented based on HTTP. The client can establish a long connection with the server through Websocket, through which the page can be updated in real time.

Code phase
  • Download Echarts in your project and introduce it

import * as echarts from “echarts”; (This is imported to the page)

  • Using Echarts diagrams on the page (scatterplot example)
export default { data() { return { dataArr: [], mychart: null, mapFunc: new Map(), }; }, methods: { chart1() { var chartDom = document.getElementById("main"); this.myChart = echarts.init(chartDom); var option; option = { xAxis: {}, yAxis: {}, series: [ { symbolSize: 20, data: this.dataArr, type: "scatter", }, ], }; option && this.myChart.setOption(option); }}},Copy the code

The data to render, dataArr, is null

  • Use Websocket to get data from the back end in real time
GetWebSocket () {/ / build connection const ws = new websocket (ws: / / 192.168.31.171:8090 / API/echarts/ws "); // Ws. onopen = (e) => {console.log(' connected '); }; Ws.onmessage = (MSG) => {let n = msg.data.split(","); const item = [Number(n[1]), Number(n[2])]; this.dataArr.push(item); // Trigger chart update this.chart1()}; // Ws.onclose = (event)=> {console.log(" webSocket Connection close."); console.log(event.code); }; // Ws.onError = (event)=> {console.log(" webSocket Connection error."); console.log(event); }; },Copy the code

Once defined, call the method in Mounted

Mounted () {// Add websocket to this.chart1(); // Add websocket to this.chart1(); this.getWebSocket(); },Copy the code

At this point, real-time updates of individual charts have been implemented

Note ⚠

Note that a

There might be a warning on the page that there is already an instance of Echarts on the page. What’s the problem? When we receive the Websocket message, we call chart1 at the end to trigger the chart update. In chart1,

      var chartDom = document.getElementById("main");
      this.myChart = echarts.init(chartDom);
Copy the code

To address this warning, I move the two lines of code inside the Mounted hook function

mounted() { var chartDom = document.getElementById("main"); this.myChart = echarts.init(chartDom); This.chart1 (); this.chart1(); this.getWebSocket(); },Copy the code

There is no warning

Note 2

The current code only shows updates to a single chart. What if there are multiple charts? It with back-end data returned by the structure of the back-end data returned by the commonly will have an attribute that is used to locate the data chart At that time the front to get the data need to judge which one is first chart, and then update the target graph That there are many kinds of practices, the judgement if, for example, can completely solve the problem, but performance is not so friendly. My solution is: use a Map structure data to store the mapping relationship between the chart name and the chart update method. When we get the data, we can call the corresponding method directly. Why use Map, because the bottom layer of Map is binary tree ~ it is very fast to find, and also saves performance

The end of the

The code here is just a small demo, only to provide ideas and methods, there is a lot of room for optimization, here is not specific ~ thank you ~