瀏覽代碼

✨ feat(设备监控): websocket测试连接

Zimo 1 天之前
父節點
當前提交
3aab25cef3
共有 6 個文件被更改,包括 465 次插入6 次删除
  1. 2 0
      index.html
  2. 198 0
      pnpm-lock.yaml
  3. 21 0
      src/views/test/index-aaa.vue
  4. 161 1
      src/views/test/index.vue
  5. 78 0
      src/views/test/useSocketBus.ts
  6. 5 5
      vite.config.ts

+ 2 - 0
index.html

@@ -3,6 +3,8 @@
   <head>
     <script src="https://g.alicdn.com/code/npm/@ali/dingtalk-h5-remote-debug/0.1.3/index.js"></script>
     <script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1.6.1/dist/sockjs.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/stompjs@2.3.3/lib/stomp.min.js"></script>
     <script async type="text/javascript" src="/js/base64.min.js"></script>
     <script src="https://api.map.baidu.com/api?v=3.0&ak=c0crhdxQ5H7WcqbcazGr7mnHrLa4GmO0"></script>
     <meta charset="UTF-8" />

+ 198 - 0
pnpm-lock.yaml

@@ -161,6 +161,9 @@ importers:
       qs:
         specifier: ^6.12.0
         version: 6.13.1
+      socket.io-client:
+        specifier: ^2.5.0
+        version: 2.5.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)
       sortablejs:
         specifier: 1.15.0
         version: 1.15.0
@@ -2405,6 +2408,9 @@ packages:
   aes-decrypter@3.1.3:
     resolution: {integrity: sha512-VkG9g4BbhMBy+N5/XodDeV6F02chEk9IpgRTq/0bS80y4dzy79VH2Gtms02VXomf3HmyRe3yyJYkJ990ns+d6A==}
 
+  after@0.8.2:
+    resolution: {integrity: sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==}
+
   ajv@6.12.6:
     resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
 
@@ -2467,6 +2473,9 @@ packages:
     resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
     engines: {node: '>=8'}
 
+  arraybuffer.slice@0.0.7:
+    resolution: {integrity: sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==}
+
   astral-regex@2.0.0:
     resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
     engines: {node: '>=8'}
@@ -2511,12 +2520,19 @@ packages:
     peerDependencies:
       '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
 
+  backo2@1.0.2:
+    resolution: {integrity: sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==}
+
   balanced-match@1.0.2:
     resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
 
   balanced-match@2.0.0:
     resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
 
+  base64-arraybuffer@0.1.4:
+    resolution: {integrity: sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==}
+    engines: {node: '>= 0.6.0'}
+
   benz-amr-recorder@1.1.5:
     resolution: {integrity: sha512-NepctcNTsZHK8NxBb5uKO5p8S+xkbm+vD6GLSkCYdJeEsriexvgumLHpDkanX4QJBcLRMVtg16buWMs+gUPB3g==}
 
@@ -2527,6 +2543,9 @@ packages:
     resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
     engines: {node: '>=8'}
 
+  blob@0.0.5:
+    resolution: {integrity: sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==}
+
   boolbase@1.0.0:
     resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
 
@@ -2576,6 +2595,10 @@ packages:
   buffer-from@1.1.2:
     resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
 
+  bufferutil@4.1.0:
+    resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==}
+    engines: {node: '>=6.14.2'}
+
   cac@6.7.14:
     resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
     engines: {node: '>=8'}
@@ -2701,9 +2724,18 @@ packages:
   compare-func@2.0.0:
     resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
 
+  component-bind@1.0.0:
+    resolution: {integrity: sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==}
+
+  component-emitter@1.3.1:
+    resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
+
   component-event@0.2.1:
     resolution: {integrity: sha512-wGA++isMqiDq1jPYeyv2as/Bt/u+3iLW0rEa+8NQ82jAv3TgqMiCM+B2SaBdn2DfLilLjjq736YcezihRYhfxw==}
 
+  component-inherit@0.0.3:
+    resolution: {integrity: sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==}
+
   compute-scroll-into-view@1.0.20:
     resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
 
@@ -3122,6 +3154,12 @@ packages:
   emoji-regex@9.2.2:
     resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
 
+  engine.io-client@3.5.6:
+    resolution: {integrity: sha512-2fDMKiXSU7bGRDCWEw9cHEdRNfoU8cpP6lt+nwJhv72tSJpO7YBsqMqYZ63eVvwX3l9prPl2k/mxhfVhY+SDWg==}
+
+  engine.io-parser@2.2.1:
+    resolution: {integrity: sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==}
+
   entities@4.5.0:
     resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
     engines: {node: '>=0.12'}
@@ -3518,6 +3556,12 @@ packages:
     resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==}
     engines: {node: '>=0.10.0'}
 
+  has-binary2@1.0.3:
+    resolution: {integrity: sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==}
+
+  has-cors@1.1.0:
+    resolution: {integrity: sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==}
+
   has-flag@4.0.0:
     resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
     engines: {node: '>=8'}
@@ -3604,6 +3648,9 @@ packages:
     resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
     engines: {node: '>=8'}
 
+  indexof@0.0.1:
+    resolution: {integrity: sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==}
+
   individual@2.0.0:
     resolution: {integrity: sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g==}
 
@@ -3692,6 +3739,9 @@ packages:
   is-url@1.2.4:
     resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==}
 
+  isarray@2.0.1:
+    resolution: {integrity: sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==}
+
   isexe@2.0.0:
     resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
 
@@ -4138,6 +4188,10 @@ packages:
       encoding:
         optional: true
 
+  node-gyp-build@4.8.4:
+    resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
+    hasBin: true
+
   node-html-parser@7.0.1:
     resolution: {integrity: sha512-KGtmPY2kS0thCWGK0VuPyOS+pBKhhe8gXztzA2ilAOhbUbxa9homF1bOyKvhGzMLXUoRds9IOmr/v5lr/lqNmA==}
 
@@ -4244,6 +4298,12 @@ packages:
   parse5@7.2.1:
     resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==}
 
+  parseqs@0.0.6:
+    resolution: {integrity: sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==}
+
+  parseuri@0.0.6:
+    resolution: {integrity: sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==}
+
   path-browserify@1.0.1:
     resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
 
@@ -4692,6 +4752,12 @@ packages:
     resolution: {integrity: sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q==}
     engines: {node: '>=12.17.0'}
 
+  socket.io-client@2.5.0:
+    resolution: {integrity: sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==}
+
+  socket.io-parser@3.3.4:
+    resolution: {integrity: sha512-z/pFQB3x+EZldRRzORYW1vwVO8m/3ILkswtnpoeU6Ve3cbMWkmHEWDAVJn4QJtchiiFTo5j7UG2QvwxvaA9vow==}
+
   sortablejs@1.14.0:
     resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==}
 
@@ -4867,6 +4933,9 @@ packages:
     resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==}
     engines: {node: '>=12.0.0'}
 
+  to-array@0.1.4:
+    resolution: {integrity: sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==}
+
   to-regex-range@5.0.1:
     resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
     engines: {node: '>=8.0'}
@@ -5015,6 +5084,10 @@ packages:
     resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==}
     engines: {node: '>= 0.4'}
 
+  utf-8-validate@5.0.10:
+    resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==}
+    engines: {node: '>=6.14.2'}
+
   util-deprecate@1.0.2:
     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
 
@@ -5259,6 +5332,18 @@ packages:
     resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
+  ws@7.5.10:
+    resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==}
+    engines: {node: '>=8.3.0'}
+    peerDependencies:
+      bufferutil: ^4.0.1
+      utf-8-validate: ^5.0.2
+    peerDependenciesMeta:
+      bufferutil:
+        optional: true
+      utf-8-validate:
+        optional: true
+
   xml-js@1.6.11:
     resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==}
     hasBin: true
@@ -5267,6 +5352,10 @@ packages:
     resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
     engines: {node: '>=12'}
 
+  xmlhttprequest-ssl@1.6.3:
+    resolution: {integrity: sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==}
+    engines: {node: '>=0.4.0'}
+
   y18n@4.0.3:
     resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
 
@@ -5307,6 +5396,9 @@ packages:
     resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
     engines: {node: '>=12'}
 
+  yeast@0.1.2:
+    resolution: {integrity: sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==}
+
   yocto-queue@0.1.0:
     resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
     engines: {node: '>=10'}
@@ -7795,6 +7887,8 @@ snapshots:
       global: 4.4.0
       pkcs7: 1.0.4
 
+  after@0.8.2: {}
+
   ajv@6.12.6:
     dependencies:
       fast-deep-equal: 3.1.3
@@ -7848,6 +7942,8 @@ snapshots:
 
   array-union@2.1.0: {}
 
+  arraybuffer.slice@0.0.7: {}
+
   astral-regex@2.0.0: {}
 
   async-validator@4.2.5: {}
@@ -7908,10 +8004,14 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
+  backo2@1.0.2: {}
+
   balanced-match@1.0.2: {}
 
   balanced-match@2.0.0: {}
 
+  base64-arraybuffer@0.1.4: {}
+
   benz-amr-recorder@1.1.5:
     dependencies:
       benz-recorderjs: 1.0.5
@@ -7920,6 +8020,8 @@ snapshots:
 
   binary-extensions@2.3.0: {}
 
+  blob@0.0.5: {}
+
   boolbase@1.0.0: {}
 
   bootstrap-icons@1.12.1: {}
@@ -7987,6 +8089,11 @@ snapshots:
 
   buffer-from@1.1.2: {}
 
+  bufferutil@4.1.0:
+    dependencies:
+      node-gyp-build: 4.8.4
+    optional: true
+
   cac@6.7.14: {}
 
   call-bind@1.0.7:
@@ -8123,8 +8230,14 @@ snapshots:
       array-ify: 1.0.0
       dot-prop: 5.3.0
 
+  component-bind@1.0.0: {}
+
+  component-emitter@1.3.1: {}
+
   component-event@0.2.1: {}
 
+  component-inherit@0.0.3: {}
+
   compute-scroll-into-view@1.0.20: {}
 
   computeds@0.0.1: {}
@@ -8574,6 +8687,32 @@ snapshots:
 
   emoji-regex@9.2.2: {}
 
+  engine.io-client@3.5.6(bufferutil@4.1.0)(utf-8-validate@5.0.10):
+    dependencies:
+      component-emitter: 1.3.1
+      component-inherit: 0.0.3
+      debug: 3.1.0
+      engine.io-parser: 2.2.1
+      has-cors: 1.1.0
+      indexof: 0.0.1
+      parseqs: 0.0.6
+      parseuri: 0.0.6
+      ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10)
+      xmlhttprequest-ssl: 1.6.3
+      yeast: 0.1.2
+    transitivePeerDependencies:
+      - bufferutil
+      - supports-color
+      - utf-8-validate
+
+  engine.io-parser@2.2.1:
+    dependencies:
+      after: 0.8.2
+      arraybuffer.slice: 0.0.7
+      base64-arraybuffer: 0.1.4
+      blob: 0.0.5
+      has-binary2: 1.0.3
+
   entities@4.5.0: {}
 
   env-paths@2.2.1: {}
@@ -9049,6 +9188,12 @@ snapshots:
     dependencies:
       ansi-regex: 2.1.1
 
+  has-binary2@1.0.3:
+    dependencies:
+      isarray: 2.0.1
+
+  has-cors@1.1.0: {}
+
   has-flag@4.0.0: {}
 
   has-property-descriptors@1.0.2:
@@ -9113,6 +9258,8 @@ snapshots:
 
   indent-string@4.0.0: {}
 
+  indexof@0.0.1: {}
+
   individual@2.0.0: {}
 
   inflight@1.0.6:
@@ -9174,6 +9321,8 @@ snapshots:
 
   is-url@1.2.4: {}
 
+  isarray@2.0.1: {}
+
   isexe@2.0.0: {}
 
   jackspeak@3.4.3:
@@ -9616,6 +9765,9 @@ snapshots:
     dependencies:
       whatwg-url: 5.0.0
 
+  node-gyp-build@4.8.4:
+    optional: true
+
   node-html-parser@7.0.1:
     dependencies:
       css-select: 5.1.0
@@ -9724,6 +9876,10 @@ snapshots:
     dependencies:
       entities: 4.5.0
 
+  parseqs@0.0.6: {}
+
+  parseuri@0.0.6: {}
+
   path-browserify@1.0.1: {}
 
   path-exists@4.0.0: {}
@@ -10125,6 +10281,32 @@ snapshots:
 
   snabbdom@3.6.2: {}
 
+  socket.io-client@2.5.0(bufferutil@4.1.0)(utf-8-validate@5.0.10):
+    dependencies:
+      backo2: 1.0.2
+      component-bind: 1.0.0
+      component-emitter: 1.3.1
+      debug: 3.1.0
+      engine.io-client: 3.5.6(bufferutil@4.1.0)(utf-8-validate@5.0.10)
+      has-binary2: 1.0.3
+      indexof: 0.0.1
+      parseqs: 0.0.6
+      parseuri: 0.0.6
+      socket.io-parser: 3.3.4
+      to-array: 0.1.4
+    transitivePeerDependencies:
+      - bufferutil
+      - supports-color
+      - utf-8-validate
+
+  socket.io-parser@3.3.4:
+    dependencies:
+      component-emitter: 1.3.1
+      debug: 3.1.0
+      isarray: 2.0.1
+    transitivePeerDependencies:
+      - supports-color
+
   sortablejs@1.14.0: {}
 
   sortablejs@1.15.0: {}
@@ -10325,6 +10507,8 @@ snapshots:
       fdir: 6.4.2(picomatch@4.0.2)
       picomatch: 4.0.2
 
+  to-array@0.1.4: {}
+
   to-regex-range@5.0.1:
     dependencies:
       is-number: 7.0.0
@@ -10502,6 +10686,11 @@ snapshots:
       punycode: 1.4.1
       qs: 6.13.1
 
+  utf-8-validate@5.0.10:
+    dependencies:
+      node-gyp-build: 4.8.4
+    optional: true
+
   util-deprecate@1.0.2: {}
 
   uuid@10.0.0: {}
@@ -10764,12 +10953,19 @@ snapshots:
       imurmurhash: 0.1.4
       signal-exit: 4.1.0
 
+  ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10):
+    optionalDependencies:
+      bufferutil: 4.1.0
+      utf-8-validate: 5.0.10
+
   xml-js@1.6.11:
     dependencies:
       sax: 1.4.1
 
   xml-name-validator@4.0.0: {}
 
+  xmlhttprequest-ssl@1.6.3: {}
+
   y18n@4.0.3: {}
 
   y18n@5.0.8: {}
@@ -10817,6 +11013,8 @@ snapshots:
       y18n: 5.0.8
       yargs-parser: 21.1.1
 
+  yeast@0.1.2: {}
+
   yocto-queue@0.1.0: {}
 
   yocto-queue@1.1.1: {}

+ 21 - 0
src/views/test/index-aaa.vue

@@ -0,0 +1,21 @@
+<template>
+  <button @click="connect">连接</button>
+  <button @click="sendHello">发送 hello</button>
+</template>
+
+<script setup lang="ts">
+import { useSocketBus } from './useSocketBus'
+
+const deviceCode = 'YF6660355'
+const { on, sendEvent, open: connect, onAny } = useSocketBus(deviceCode)
+
+// 注册自定义事件
+on('server_reply_msg', (data) => console.log('📥 后端回复:', data))
+on('device_push_msg', (data) => console.log('📤 后端推送:', data))
+
+onAny((msg) => console.log('📡 任意事件:', msg))
+
+function sendHello() {
+  sendEvent('client_send_msg', { text: 'hello from useWebSocket', time: Date.now() })
+}
+</script>

+ 161 - 1
src/views/test/index.vue

@@ -1,4 +1,4 @@
-<script lang="ts" setup>
+<!-- <script lang="ts" setup>
 import { IotDeviceApi } from '@/api/pms/device'
 import { SortField } from '@/components/ZmTable/token'
 import { useTableComponents } from '@/components/ZmTable/useTableComponents'
@@ -93,4 +93,164 @@ const realValue = (value: string) => {
       <zm-table-column zm-filterable zm-sortable prop="assetOwnership" label="资产归属" />
     </zm-table>
   </div>
+</template> -->
+
+<script lang="ts" setup>
+// import { io, Socket } from 'socket.io-client'
+
+// let socket: Socket | null = null
+// const deviceCode = 'YF6660355'
+
+// /**
+//  * 连接
+//  */
+// function connect(): void {
+//   // const wsUrl = `http://121.36.34.44:8099/ws/device`
+//   const wsUrl = `http://121.36.34.44:8099/ws/device/${deviceCode}`
+//   // const wsUrl = `http://localhost:80`
+//   socket = io(wsUrl, {
+//     transports: ['websocket'],
+//     reconnection: true,
+//     withCredentials: true,
+//     reconnectionAttempts: 5,
+//     upgrade: false,
+//     timeout: 5000
+//   })
+
+//   socket.on('connect', () => {
+//     console.log('✅ socket.io 连接成功', socket?.id)
+//   })
+
+//   socket.on('server_reply_msg', (data) => {
+//     console.log(`📥 后端回复:${data}`)
+//   })
+
+//   socket.on('device_push_msg', (data) => {
+//     console.log(`📤 后端推送:${JSON.stringify(data)}`)
+//   })
+
+//   socket.on('disconnect', (reason) => {
+//     console.log('🔌 断开连接', reason)
+//   })
+
+//   socket.on('connect_error', (err) => {
+//     console.error('❌ 连接失败', err)
+//   })
+
+//   // 接收后端推送(等价于 /topic/device/{deviceCode})
+//   socket.on('device-msg', (data) => {
+//     console.log('📩 收到消息:', data)
+//   })
+// }
+
+// /**
+//  * 发送消息
+//  */
+// function sendMsg(): void {
+//   if (!socket || !socket.connected) {
+//     console.warn('⚠️ 还没连接')
+//     return
+//   }
+
+//   socket.emit('client_send_msg', {
+//     deviceCode,
+//     text: 'hello from socket.io',
+//     time: Date.now()
+//   })
+
+//   console.log('📤 消息已发送')
+// }
+
+// /**
+//  * 主动断开
+//  */
+// function disconnect(): void {
+//   socket?.disconnect()
+//   socket = null
+//   console.log('🔌 已主动断开')
+// }
+
+import io, { Socket } from 'socket.io-client'
+
+let socket: Socket | null = null
+const deviceCode = 'YF6660355'
+
+/**
+ * 连接
+ */
+function connect(): void {
+  const wsUrl = `http://121.36.34.44:8099/ws/device/${deviceCode}`
+
+  socket = io(wsUrl, {
+    // v2 里 transports 可以直接写数组
+    transports: ['websocket'],
+    // 是否自动重连
+    reconnection: true,
+    // 重连次数
+    reconnectionAttempts: 5,
+    // 重连间隔
+    reconnectionDelay: 1000,
+    // 超时时间
+    timeout: 5000
+    // 注意 v2 里没有 withCredentials 选项
+  })
+
+  socket.on('connect', () => {
+    console.log('✅ socket.io 连接成功', socket?.id)
+  })
+
+  socket.on('server_reply_msg', (data: any) => {
+    console.log(`📥 后端回复:${data}`)
+  })
+
+  socket.on('device_push_msg', (data: any) => {
+    console.log(`📤 后端推送:${JSON.stringify(data)}`)
+  })
+
+  socket.on('disconnect', (reason: string) => {
+    console.log('🔌 断开连接', reason)
+  })
+
+  socket.on('connect_error', (err: any) => {
+    console.error('❌ 连接失败', err)
+  })
+
+  // 设备消息推送
+  socket.on('device-msg', (data: any) => {
+    console.log('📩 收到消息:', data)
+  })
+}
+
+/**
+ * 发送消息
+ */
+function sendMsg(): void {
+  if (!socket || !socket.connected) {
+    console.warn('⚠️ 还没连接')
+    return
+  }
+
+  socket.emit('client_send_msg', {
+    deviceCode,
+    text: 'hello from socket.io',
+    time: Date.now()
+  })
+
+  console.log('📤 消息已发送')
+}
+
+/**
+ * 主动断开
+ */
+function disconnect(): void {
+  socket?.disconnect()
+  socket = null
+  console.log('🔌 已主动断开')
+}
+</script>
+
+<template>
+  <button @click="connect">连接</button>
+  <button @click="sendMsg">发送</button>
+  <button @click="disconnect">断开</button>
 </template>

+ 78 - 0
src/views/test/useSocketBus.ts

@@ -0,0 +1,78 @@
+import { ref, reactive } from 'vue'
+import { useWebSocket } from '@vueuse/core'
+
+type EventHandler = (data: any) => void
+
+export function useSocketBus(deviceCode: string) {
+  const url = `ws://192.168.188.149:8080/ws/${deviceCode}`
+
+  // 响应式状态
+  const status = ref<'CONNECTING' | 'OPEN' | 'CLOSED'>('CLOSED')
+  const messages = ref<any[]>([])
+
+  // 事件总线
+  const events: Record<string, EventHandler[]> = reactive({})
+
+  // 创建 WebSocket
+  const { ws, open, close, send } = useWebSocket(url, {
+    immediate: false,
+    autoReconnect: {
+      retries: 5,
+      delay: 1000
+    },
+    onConnected(_ws) {
+      console.log('✅ WebSocket 已连接')
+      status.value = 'OPEN'
+    },
+    onDisconnected() {
+      console.log('🔌 WebSocket 已断开')
+      status.value = 'CLOSED'
+    },
+    onMessage(_ws, event) {
+      try {
+        const msg = JSON.parse(event.data)
+        messages.value.push(msg)
+        if (msg.event && events[msg.event]) {
+          events[msg.event].forEach((cb) => cb(msg.data))
+        }
+
+        anyHandlers.forEach((cb) => cb(msg))
+      } catch (err) {
+        console.warn('非 JSON 消息:', event.data)
+      }
+    }
+  })
+
+  const anyHandlers: EventHandler[] = reactive([])
+
+  // 注册所有事件回调
+  function onAny(cb: EventHandler) {
+    anyHandlers.push(cb)
+  }
+
+  // 注册事件
+  function on(eventName: string, cb: EventHandler) {
+    if (!events[eventName]) events[eventName] = []
+    events[eventName].push(cb)
+  }
+
+  // 注销事件
+  function off(eventName: string, cb?: EventHandler) {
+    if (!cb) {
+      events[eventName] = []
+    } else {
+      events[eventName] = (events[eventName] || []).filter((fn) => fn !== cb)
+    }
+  }
+
+  // 发送带事件名的消息
+  function sendEvent(eventName: string, data: any) {
+    if (ws.value?.readyState === WebSocket.OPEN) {
+      send(JSON.stringify({ event: eventName, data }))
+    } else {
+      console.warn('⚠️ WebSocket 未连接')
+    }
+  }
+
+  return { ws, status, messages, on, off, sendEvent, open, close, onAny }
+}

+ 5 - 5
vite.config.ts

@@ -1,8 +1,8 @@
-import {resolve} from 'path'
-import type {ConfigEnv, UserConfig} from 'vite'
-import {loadEnv} from 'vite'
-import {createVitePlugins} from './build/vite'
-import {exclude, include} from "./build/vite/optimize"
+import { resolve } from 'path'
+import type { ConfigEnv, UserConfig } from 'vite'
+import { loadEnv } from 'vite'
+import { createVitePlugins } from './build/vite'
+import { include } from "./build/vite/optimize"
 // 当前执行node命令时文件夹的地址(工作目录)
 const root = process.cwd()