| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>WebSocket设备数据测试</title>
- <style>
- body {
- font-family: Arial, sans-serif;
- margin: 20px;
- padding: 20px;
- background-color: #f5f5f5;
- }
- .container {
- max-width: 1200px;
- margin: 0 auto;
- background-color: white;
- padding: 20px;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
- }
- .status {
- padding: 10px;
- margin: 10px 0;
- border-radius: 4px;
- }
- .status.connected {
- background-color: #d4edda;
- color: #155724;
- border: 1px solid #c3e6cb;
- }
- .status.disconnected {
- background-color: #f8d7da;
- color: #721c24;
- border: 1px solid #f5c6cb;
- }
- button {
- background-color: #007bff;
- color: white;
- border: none;
- padding: 10px 20px;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- margin: 5px;
- }
- button:hover {
- background-color: #0056b3;
- }
- button:disabled {
- background-color: #cccccc;
- cursor: not-allowed;
- }
- .equipment-list {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
- gap: 10px;
- margin-top: 20px;
- }
- .equipment-item {
- padding: 10px;
- border: 1px solid #ddd;
- border-radius: 4px;
- background-color: #f9f9f9;
- }
- .equipment-item.changed {
- background-color: #fff3cd;
- border-color: #ffc107;
- animation: highlight 2s;
- }
- @keyframes highlight {
- 0% { background-color: #ffc107; }
- 100% { background-color: #fff3cd; }
- }
- .equipment-name {
- font-weight: bold;
- margin-bottom: 5px;
- }
- .equipment-value {
- color: #007bff;
- font-size: 18px;
- }
- .equipment-type {
- color: #666;
- font-size: 12px;
- }
- .stats {
- display: flex;
- gap: 20px;
- margin: 20px 0;
- padding: 10px;
- background-color: #e9ecef;
- border-radius: 4px;
- }
- .stat-item {
- display: flex;
- flex-direction: column;
- }
- .stat-label {
- font-size: 12px;
- color: #666;
- }
- .stat-value {
- font-size: 18px;
- font-weight: bold;
- }
- .log-container {
- margin-top: 20px;
- border: 1px solid #ddd;
- border-radius: 4px;
- padding: 10px;
- height: 200px;
- overflow-y: auto;
- background-color: #f9f9f9;
- }
- .log-entry {
- margin: 5px 0;
- padding: 5px;
- border-bottom: 1px solid #eee;
- font-size: 12px;
- }
- .log-entry.info {
- color: #007bff;
- }
- .log-entry.error {
- color: #dc3545;
- }
- .log-entry.success {
- color: #28a745;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <h1>WebSocket设备数据实时推送测试</h1>
- <div id="status" class="status disconnected">
- 状态: 未连接
- </div>
- <div>
- <button id="connectBtn" onclick="connect()">连接WebSocket</button>
- <button id="disconnectBtn" onclick="disconnect()" disabled>断开连接</button>
- <button onclick="clearLog()">清空日志</button>
- <button onclick="clearEquipment()">清空设备列表</button>
- </div>
- <div class="stats">
- <div class="stat-item">
- <span class="stat-label">设备数量</span>
- <span class="stat-value" id="equipmentCount">0</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">接收消息数</span>
- <span class="stat-value" id="messageCount">0</span>
- </div>
- <div class="stat-item">
- <span class="stat-label">线路号</span>
- <span class="stat-value" id="lineID">0</span>
- </div>
- </div>
- <h2>设备列表</h2>
- <div id="equipmentList" class="equipment-list"></div>
- <h2>连接日志</h2>
- <div id="logContainer" class="log-container"></div>
- </div>
- <script>
- let ws = null;
- let messageCount = 0;
- let equipmentData = {};
- function connect() {
- // 根据当前页面协议选择ws或wss
- const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
- const host = window.location.host;
- const url = `${protocol}//${host}/ws/equipment`;
- log('info', `正在连接到WebSocket: ${url}`);
- ws = new WebSocket(url);
- ws.onopen = function(event) {
- log('success', 'WebSocket连接成功');
- updateStatus(true);
- document.getElementById('connectBtn').disabled = true;
- document.getElementById('disconnectBtn').disabled = false;
- };
- ws.onmessage = function(event) {
- messageCount++;
- document.getElementById('messageCount').textContent = messageCount;
- try {
- const message = JSON.parse(event.data);
- if (message.event === 'connected') {
- log('success', `已连接,客户端ID: ${message.data.clientID},线路号: ${message.data.lineID}`);
- document.getElementById('lineID').textContent = message.data.lineID || 0;
- } else if (Array.isArray(message)) {
- // 直接处理设备数组
- log('info', `收到设备数据,数量: ${message.length}`);
- updateEquipmentList(message);
- document.getElementById('equipmentCount').textContent = message.length;
- }
- } catch (e) {
- log('error', `解析消息失败: ${e.message}`);
- }
- };
- ws.onerror = function(event) {
- log('error', 'WebSocket发生错误');
- console.error('WebSocket error:', event);
- };
- ws.onclose = function(event) {
- log('info', 'WebSocket连接已关闭');
- updateStatus(false);
- document.getElementById('connectBtn').disabled = false;
- document.getElementById('disconnectBtn').disabled = true;
- };
- }
- function disconnect() {
- if (ws) {
- ws.close();
- ws = null;
- }
- }
- function updateStatus(connected) {
- const statusDiv = document.getElementById('status');
- if (connected) {
- statusDiv.className = 'status connected';
- statusDiv.textContent = '状态: 已连接';
- } else {
- statusDiv.className = 'status disconnected';
- statusDiv.textContent = '状态: 未连接';
- }
- }
- function updateEquipmentList(equipments) {
- const container = document.getElementById('equipmentList');
- // 标记现有设备
- const existingElements = {};
- container.querySelectorAll('.equipment-item').forEach(element => {
- existingElements[element.dataset.id] = element;
- });
- // 更新或添加设备
- equipments.forEach(equip => {
- let element = existingElements[equip.id];
- const oldValue = equipmentData[equip.id];
- // 检查值是否变化
- const valueChanged = oldValue !== undefined && oldValue !== equip.value;
- if (element) {
- // 更新现有设备
- const valueElement = element.querySelector('.equipment-value');
- valueElement.textContent = equip.value;
- if (valueChanged) {
- element.classList.add('changed');
- setTimeout(() => {
- element.classList.remove('changed');
- }, 2000);
- }
- // 移除已处理标记
- delete existingElements[equip.id];
- } else {
- // 添加新设备
- element = document.createElement('div');
- element.className = 'equipment-item changed';
- element.dataset.id = equip.id;
- element.innerHTML = `
- <div class="equipment-name">${equip.dataName}</div>
- <div class="equipment-value">${equip.value}</div>
- <div class="equipment-type">ID: ${equip.dataId}</div>
- `;
- container.appendChild(element);
- setTimeout(() => {
- element.classList.remove('changed');
- }, 2000);
- }
- // 更新数据缓存
- equipmentData[equip.id] = equip.value;
- });
- // 移除不存在的设备
- Object.values(existingElements).forEach(element => {
- element.remove();
- const id = element.dataset.id;
- delete equipmentData[id];
- });
- }
- function log(type, message) {
- const container = document.getElementById('logContainer');
- const entry = document.createElement('div');
- entry.className = `log-entry ${type}`;
- const time = new Date().toLocaleTimeString();
- entry.textContent = `[${time}] ${message}`;
- container.insertBefore(entry, container.firstChild);
- // 限制日志条数
- while (container.children.length > 100) {
- container.removeChild(container.lastChild);
- }
- }
- function clearLog() {
- document.getElementById('logContainer').innerHTML = '';
- }
- function clearEquipment() {
- document.getElementById('equipmentList').innerHTML = '';
- equipmentData = {};
- }
- // 页面加载时自动连接
- window.onload = function() {
- log('info', '页面已加载,点击"连接WebSocket"按钮开始连接');
- };
- </script>
- </body>
- </html>
|