Plantilla de pantalla grande, aumento adaptable (incluido websocket)

1. Servidor de nodo simple

const WebSocket = require('ws');

// 创建 WebSocket 服务器
const wss = new WebSocket.Server({ port: 8888 });

const getHeader = (protocol) => {
  const protocolArr = protocol.split(',')
  const headers = {};
  for (let i = 0; i < protocolArr.length; i += 2) {
    const key = protocolArr[i].trim();
    const value = protocolArr[i + 1].trim();
    headers[key] = value;
  }

  return headers;
}
let timer = null;
let num = 0;
let UID = '';

// 监听连接事件
wss.on('connection', (ws, req) => {
  const userName = req.url.replace('/', '');
  UID = userName;
  console.log('WebSocket connection established for URL:', userName);
  // 在 'upgrade' 事件处理程序中获取请求头信息
  const protocol = req.headers['sec-websocket-protocol'];
  console.log('Sec-WebSocket-Protocol:', getHeader(protocol)['X-Access-Token']);


  // 连接建立成功时触发
  console.log('Client connected');
  if(!timer) {
    const obj = [
      {
        name: 'SC001',
        value: 123
      },
      {
        name: 'SC001',
        value: 123
      }
    ]
    timer = setInterval(() => {
      ws.send(`${UID}心跳信息消息: ${num}--${JSON.stringify(obj)}`);
      num++
    }, 3000);
  }

  // 监听消息接收事件
  ws.on('message', (message) => {
    console.log(`Received message: ${message}`);

    // 向客户端发送消息
    ws.send(`服务端返回消息: ${message}`);
  });

  // 监听连接关闭事件
  ws.on('close', () => {
    // 连接关闭时触发
    console.log('Client disconnected');
    timer = null;
  });
});

2. Cliente de pantalla grande

<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>大屏测试</title>
</head>

<body>
  <style>
    body {
      position: relative;
      margin: 0;
      padding: 0;
      color: #ffffff;
      font-size: 36px;
      font-weight: bold;
      background-color: #20f;
      background-color: #3084e7;
      background: url(https://tinypng.com/backend/opt/output/3ret9c4gdpxnargyh99c1rgj1ne52res/bg.png) no-repeat;
      background-size: auto;
    }

    .item {
      box-shadow: inset 0px 0px 6px 2px #9df6fa;
      border-radius: 4px;
      width: calc(100% - 24px);
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 12px;
    }

    .bigscreen {
      margin: 12px;
      display: flex;
      height: 100%;
    }

    .mg12 {
      margin: 12px 0;
    }

    .header {
      margin: 0 12px;
      text-align: center;
      line-height: 48px;
      margin-bottom: 12px;
      font-size: 36px;
      background: linear-gradient(to bottom, #56f4fe, #3084e7);
      -webkit-background-clip: text;
      color: transparent;
    }
    .first {
      display: flex;
      justify-content: space-around;
      align-items: center;
      font-size: 22px;
    }
    .i {
      width: 100%;
      display: flex;
      flex-direction: column;
      text-align: center;
    }
    .val {
      margin-top: 12px;
    }
  </style>
  <div id="app" style="position: absolute;">
    <div class="header">大屏标题</div>
    <div class="bigscreen">
      <div style="display: flex;flex-direction: column; height: calc(100% - 72px); width: 65%; margin-right: 12px;">
        <div id="first" class="item first" style="height: 15%;">
          <div class="i">
            <div>API总数</div>
            <div class="val">19,612</div>
          </div>
          <div class="i">
            <div>调用数</div>
            <div class="val">1,222</div>
          </div>
          <div class="i" id="warn" style="color: red;">
            <div>告警数</div>
            <div class="val">68</div>
          </div>
        </div>
        <div id="chart2" class="item mg12" style="height: 30%;">222</div>
        <div id="chart3" class="item" style="flex: 1;">333</div>
      </div>
      <div style="display: flex;flex-direction: column; height: calc(100% - 72px); flex: 1;">
        <div id="chart4" class="item">111</div>
        <div id="chart5" class="item mg12">222</div>
        <div id="chart6" class="item">333</div>
      </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
  <script type="module">
    import autofit from 'https://cdn.jsdelivr.net/npm/autofit.js';

    autofit.init(
      {
        dh: 1080,
        dw: 1920,
        el: '#app',
        resize: true
      },
      false
    );

    // 配置图表选项和数据
    const obj = ['bar', 'line']
    const getType = () => {
      // 生成随机索引
      var randomIndex = Math.floor(Math.random() * obj.length);
      // 获取随机元素
      var type = obj[randomIndex];
      return type;
    }
    var option = () => {
      const type = getType()
      return {
        color: ['#80FFA5', '#00DDFF', '#37A2FF', '#FF0087', '#FFBF00'],
        title: {
          text: 'Gradient Stacked Area Chart'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross',
            label: {
              backgroundColor: '#6a7985'
            }
          }
        },
        legend: {
          data: ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']
        },
        toolbox: {
          feature: {
            saveAsImage: {}
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            boundaryGap: type === 'bar',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
          }
        ],
        yAxis: [
          {
            type: 'value'
          }
        ],
        series: [
          {
            name: 'Line 1',
            type: type,
            stack: 'Total',
            smooth: true,
            lineStyle: {
              width: 0
            },
            showSymbol: false,
            areaStyle: {
              opacity: 0.8,
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: 'rgb(128, 255, 165)'
                },
                {
                  offset: 1,
                  color: 'rgb(1, 191, 236)'
                }
              ])
            },
            emphasis: {
              focus: 'series'
            },
            data: [Math.random() * 1000, Math.random() * 100, 101, 264, 90, 340, 250]
          },
          {
            name: 'Line 2',
            type: type,
            stack: 'Total',
            smooth: true,
            lineStyle: {
              width: 0
            },
            showSymbol: false,
            areaStyle: {
              opacity: 0.8,
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: 'rgb(0, 221, 255)'
                },
                {
                  offset: 1,
                  color: 'rgb(77, 119, 255)'
                }
              ])
            },
            emphasis: {
              focus: 'series'
            },
            data: [Math.random() * 1000, Math.random() * 100, 111, 234, 220, 340, 310]
          },
          {
            name: 'Line 3',
            type: type,
            stack: 'Total',
            smooth: true,
            lineStyle: {
              width: 0
            },
            showSymbol: false,
            areaStyle: {
              opacity: 0.8,
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: 'rgb(55, 162, 255)'
                },
                {
                  offset: 1,
                  color: 'rgb(116, 21, 219)'
                }
              ])
            },
            emphasis: {
              focus: 'series'
            },
            data: [Math.random() * 1000, Math.random() * 100, 201, 334, 190, 130, 220]
          },
        ]
      }
    };

    // 初始化ECharts实例
    var myChart2 = echarts.init(document.getElementById('chart2'), 'dark');
    var myChart3 = echarts.init(document.getElementById('chart3'), 'dark');
    var myChart4 = echarts.init(document.getElementById('chart4'), 'dark');
    var myChart5 = echarts.init(document.getElementById('chart5'), 'dark');
    var myChart6 = echarts.init(document.getElementById('chart6'), 'dark');

    // 使用配置项设置图表
    myChart2.setOption(option());
    myChart3.setOption(option());
    myChart4.setOption(option());
    myChart5.setOption(option());
    myChart6.setOption(option());

    // 自适应窗口大小变化
    window.addEventListener('resize', function () {
      myChart2.resize();
      myChart3.resize();
      myChart4.resize();
      myChart5.resize();
      myChart6.resize();
    });

    const timer = setInterval(() => {
      myChart2.setOption(option());
      myChart3.setOption(option());
      myChart4.setOption(option());
      myChart5.setOption(option());
      myChart6.setOption(option());
    }, 3000);
  </script>
  <script>
    setTimeout(() => {
      // 创建一个 Canvas 元素
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
    
      // 设置 Canvas 的尺寸与容器元素相同
      var container = document.getElementById('first');
      canvas.width = container.offsetWidth * 0.6;
      canvas.height = container.offsetHeight;
  
      var date = new Date();
      var month = date.getMonth() + 1;
      var time = `${date.getFullYear()}-${month > 9 ? month : '0'+month}-${date.getDate()}  ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
    
      // 旋转绘图上下文45度(以弧度为单位)
      ctx.rotate(Math.PI / 16);
      // 绘制水印文本
      ctx.font = '36px Arial';
      ctx.fillStyle = '#ffffff1f'; // 水印文本颜色和透明度
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(time, canvas.width / 4, canvas.height / 4);
    
      // 将 Canvas 转换为背景图像
      var watermarkUrl = canvas.toDataURL();
    
      // 设置容器元素的背景样式为水印图像
      container.style.backgroundImage = 'url(' + watermarkUrl + ')';
    }, 200)
  </script>
  <script>
    let socket, timers, connectState;
    let num = 1;
    const TIME = 10

    // 创建 WebSocket 连接函数
    function createWebSocket(state) {
      if(state) {
        num = 1;
        document.getElementById("output").innerHTML = '';
        console.clear()
      }
      const room = new Date().getTime();
      const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2ODg1MzgzNDUsInVzZXJuYW1lIjoiYWRtaW4ifQ.Yac09LCyIAwjUofsm2cvGKxPmpZ5fTXG9ZKpFYdX2eQ';
      socket = new WebSocket("ws:localhost:8888/tengyu?id=001", ['X-Access-Token', token, 'Authorization', "token"]);
      // socket = new WebSocket(`ws://10.72.30.229:8080/dsss/websocket/largeScreen/room-${room}`);
      
      // 监听连接打开事件
      socket.onopen = function(event) {
        connectState = true;
      };

      // 监听消息接收事件
      socket.onmessage = function(event) {
        console.log(event.data);
      };

      // 监听连接关闭事件
      socket.onclose = function(event) {
        connectState = false;

        // 断线后尝试重连
        timers = setTimeout(function() {
          if (num > TIME) {
            clearTimeout(timers);
            console.log(`%cWS连接失败,如需重连请点击【连接WebSocket】`, 'background: blue; color: #fff; padding: 8px 12px; border-radius: 3px');
            return;
          }
          console.log(`%cWS第${num}次断线重连中...`, 'background: red; color: #fff; padding: 8px 12px; border-radius: 3px');
          createWebSocket();
          num++
        }, 5000);
      };
    }

    function fangdou(callback, time = 500) {
      let timers = null;
      
      return function() {
        if(timers) {
          clearTimeout(timers);
        }
        timers = setTimeout(() => {
          callback.apply(this, arguments);
          timers = null;
        }, time);
      };
    }

    // 发送消息到 WebSocket 服务器
    function sendMessage() {
      if(!connectState) {
        console.log(`WS服务器未连接~`);
        return;
      } 
      const message = prompt("Enter your message:");
      console.log(`发送到服务器: ${messages}`);
      socket.send(messages);
    }
    // 初始化 WebSocket 连接
    createWebSocket();
  </script>
  
</body>

</html>

Supongo que te gusta

Origin blog.csdn.net/qq_23334071/article/details/132401541
Recomendado
Clasificación