diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..06019d5 --- /dev/null +++ b/.env.development @@ -0,0 +1,7 @@ +ENV = 'development' + +# 客户端版本 +VITE_CLIENT_VERSION = 789654 + +# ws地址 +VITE_WS_URL = 'ws://localhost:80/ws' \ No newline at end of file diff --git a/.gitignore b/.gitignore index fe397f9..23348ee 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,4 @@ coverage *.sw? *.tsbuildinfo -*.local +note.md diff --git a/package.json b/package.json index 74280fa..717d013 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore", "format": "prettier --write src/", "prepare": "husky install", - "lint-staged": "lint-staged" + "lint-staged": "lint-staged", + "proto": "npx pbjs -t static-module --es6 -w es6 -o src/proto/msg.js src/proto/msg.proto" }, "dependencies": { "@element-plus/icons-vue": "^2.3.1", @@ -21,6 +22,7 @@ "element-plus": "^2.8.0", "lodash": "^4.17.21", "pinia": "^2.1.7", + "protobufjs": "^7.4.0", "uuid": "^10.0.0", "vue": "^3.4.29", "vue-router": "^4.3.3" @@ -35,6 +37,7 @@ "lint-staged": "^15.2.9", "pinia-plugin-persistedstate": "^3.2.1", "prettier": "^3.2.5", + "protobufjs-cli": "^1.1.3", "sass": "^1.77.8", "unplugin-auto-import": "^0.18.2", "unplugin-vue-components": "^0.27.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a8453c8..23ac6c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: pinia: specifier: ^2.1.7 version: 2.2.2(vue@3.4.38) + protobufjs: + specifier: ^7.4.0 + version: 7.4.0 uuid: specifier: ^10.0.0 version: 10.0.0 @@ -47,7 +50,7 @@ importers: version: 1.10.4 '@vitejs/plugin-vue': specifier: ^5.0.5 - version: 5.1.2(vite@5.4.1(sass@1.77.8))(vue@3.4.38) + version: 5.1.2(vite@5.4.1(@types/node@22.5.4)(sass@1.77.8))(vue@3.4.38) '@vue/eslint-config-prettier': specifier: ^9.0.0 version: 9.0.0(eslint@8.57.0)(prettier@3.3.3) @@ -69,6 +72,9 @@ importers: prettier: specifier: ^3.2.5 version: 3.3.3 + protobufjs-cli: + specifier: ^1.1.3 + version: 1.1.3(protobufjs@7.4.0) sass: specifier: ^1.77.8 version: 1.77.8 @@ -77,10 +83,10 @@ importers: version: 0.18.2(@vueuse/core@9.13.0(vue@3.4.38))(rollup@4.21.0) unplugin-vue-components: specifier: ^0.27.4 - version: 0.27.4(@babel/parser@7.25.3)(rollup@4.21.0)(vue@3.4.38) + version: 0.27.4(@babel/parser@7.25.6)(rollup@4.21.0)(vue@3.4.38) vite: specifier: ^5.3.1 - version: 5.4.1(sass@1.77.8) + version: 5.4.1(@types/node@22.5.4)(sass@1.77.8) packages: @@ -100,6 +106,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.25.6': + resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/runtime@7.25.6': resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==} engines: {node: '>=6.9.0'} @@ -108,6 +119,10 @@ packages: resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.25.6': + resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} + engines: {node: '>=6.9.0'} + '@ctrl/tinycolor@3.6.1': resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} engines: {node: '>=10'} @@ -297,6 +312,10 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jsdoc/salty@0.2.8': + resolution: {integrity: sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==} + engines: {node: '>=v12.0.0'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -313,6 +332,36 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@rollup/pluginutils@5.1.0': resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -417,12 +466,24 @@ packages: '@types/event-emitter@0.3.5': resolution: {integrity: sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ==} + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} '@types/lodash@4.17.7': resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/node@22.5.4': + resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} + '@types/web-bluetooth@0.0.16': resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} @@ -643,6 +704,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -660,6 +724,10 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + catharsis@0.9.0: + resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==} + engines: {node: '>= 10'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -787,6 +855,10 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -795,6 +867,11 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + escodegen@1.14.3: + resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} + engines: {node: '>=4.0'} + hasBin: true + eslint-config-prettier@9.1.0: resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true @@ -842,6 +919,11 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -850,6 +932,10 @@ packages: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -956,10 +1042,17 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -1058,6 +1151,14 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + js2xmlparser@4.0.2: + resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} + + jsdoc@4.0.3: + resolution: {integrity: sha512-Nu7Sf35kXJ1MWDZIMAuATRQTg1iIPdzh7tqJ6jjvaU/GfDf+qi5UV8zJR3Mo+/pYFvm8mzay4+6O5EWigaQBQw==} + engines: {node: '>=12.0.0'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -1070,6 +1171,13 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + klaw@3.0.0: + resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1078,6 +1186,9 @@ packages: resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} engines: {node: '>=14'} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + lint-staged@15.2.9: resolution: {integrity: sha512-BZAt8Lk3sEnxw7tfxM7jeZlPRuT4M68O0/CwZhhaw6eeWu0Lz5eERE3m386InivXB64fp/mDID452h48tvKlRQ==} engines: {node: '>=18.12.0'} @@ -1136,9 +1247,30 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} + long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + markdown-it-anchor@8.6.7: + resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} + peerDependencies: + '@types/markdown-it': '*' + markdown-it: '*' + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + memoize-one@6.0.0: resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} @@ -1175,10 +1307,22 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} @@ -1224,6 +1368,10 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1302,6 +1450,10 @@ packages: preact@10.23.2: resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1319,9 +1471,24 @@ packages: resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} engines: {node: '>=6'} + protobufjs-cli@1.1.3: + resolution: {integrity: sha512-MqD10lqF+FMsOayFiNOdOGNlXc4iKDCf0ZQPkPR+gizYh9gqUeGTWulABUCdI+N67w5RfJ6xhgX4J8pa8qmMXQ==} + engines: {node: '>=12.0.0'} + hasBin: true + peerDependencies: + protobufjs: ^7.0.0 + + protobufjs@7.4.0: + resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} + engines: {node: '>=12.0.0'} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1336,6 +1503,9 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + requizzle@0.2.4: + resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -1415,6 +1585,10 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + ssr-window@3.0.0: resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==} @@ -1459,6 +1633,10 @@ packages: tiny-warning@1.0.3: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -1470,6 +1648,10 @@ packages: tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -1481,9 +1663,23 @@ packages: type@2.7.3: resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + underscore@1.13.7: + resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + unimport@3.10.0: resolution: {integrity: sha512-/UvKRfWx3mNDWwWQhR62HsoM3wxHwYdTq8ellZzMOHnnw4Dp8tovgthyW7DjTrbjDL+i4idOp06voz2VKlvrLw==} @@ -1617,6 +1813,9 @@ packages: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} + xmlcreate@2.0.4: + resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} + yaml@2.5.0: resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} engines: {node: '>= 14'} @@ -1638,6 +1837,11 @@ snapshots: dependencies: '@babel/types': 7.25.2 + '@babel/parser@7.25.6': + dependencies: + '@babel/types': 7.25.6 + optional: true + '@babel/runtime@7.25.6': dependencies: regenerator-runtime: 0.14.1 @@ -1648,6 +1852,13 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@babel/types@7.25.6': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + optional: true + '@ctrl/tinycolor@3.6.1': {} '@element-plus/icons-vue@2.3.1(vue@3.4.38)': @@ -1771,6 +1982,10 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} + '@jsdoc/salty@0.2.8': + dependencies: + lodash: 4.17.21 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1785,6 +2000,29 @@ snapshots: '@pkgr/core@0.1.1': {} + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + '@rollup/pluginutils@5.1.0(rollup@4.21.0)': dependencies: '@types/estree': 1.0.5 @@ -1851,12 +2089,25 @@ snapshots: '@types/event-emitter@0.3.5': {} + '@types/linkify-it@5.0.0': {} + '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.7 '@types/lodash@4.17.7': {} + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdurl@2.0.0': {} + + '@types/node@22.5.4': + dependencies: + undici-types: 6.19.8 + '@types/web-bluetooth@0.0.16': {} '@ungap/structured-clone@1.2.0': {} @@ -1890,9 +2141,9 @@ snapshots: '@uppy/utils': 4.1.3 nanoid: 3.3.7 - '@vitejs/plugin-vue@5.1.2(vite@5.4.1(sass@1.77.8))(vue@3.4.38)': + '@vitejs/plugin-vue@5.1.2(vite@5.4.1(@types/node@22.5.4)(sass@1.77.8))(vue@3.4.38)': dependencies: - vite: 5.4.1(sass@1.77.8) + vite: 5.4.1(@types/node@22.5.4)(sass@1.77.8) vue: 3.4.38 '@vue/compiler-core@3.4.38': @@ -2137,6 +2388,8 @@ snapshots: binary-extensions@2.3.0: {} + bluebird@3.7.2: {} + boolbase@1.0.0: {} brace-expansion@1.1.11: @@ -2154,6 +2407,10 @@ snapshots: callsites@3.1.0: {} + catharsis@0.9.0: + dependencies: + lodash: 4.17.21 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -2310,10 +2567,21 @@ snapshots: escape-html@1.0.3: {} + escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} + escodegen@1.14.3: + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + eslint-config-prettier@9.1.0(eslint@8.57.0): dependencies: eslint: 8.57.0 @@ -2404,6 +2672,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 3.4.3 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -2412,6 +2682,8 @@ snapshots: dependencies: estraverse: 5.3.0 + estraverse@4.3.0: {} + estraverse@5.3.0: {} estree-walker@2.0.2: {} @@ -2520,10 +2792,20 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + globals@13.24.0: dependencies: type-fest: 0.20.2 + graceful-fs@4.2.11: {} + graphemer@1.4.0: {} has-flag@4.0.0: {} @@ -2594,6 +2876,28 @@ snapshots: dependencies: argparse: 2.0.1 + js2xmlparser@4.0.2: + dependencies: + xmlcreate: 2.0.4 + + jsdoc@4.0.3: + dependencies: + '@babel/parser': 7.25.3 + '@jsdoc/salty': 0.2.8 + '@types/markdown-it': 14.1.2 + bluebird: 3.7.2 + catharsis: 0.9.0 + escape-string-regexp: 2.0.0 + js2xmlparser: 4.0.2 + klaw: 3.0.0 + markdown-it: 14.1.0 + markdown-it-anchor: 8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.0) + marked: 4.3.0 + mkdirp: 1.0.4 + requizzle: 0.2.4 + strip-json-comments: 3.1.1 + underscore: 1.13.7 + json-buffer@3.0.1: {} json-schema-traverse@0.4.1: {} @@ -2604,6 +2908,15 @@ snapshots: dependencies: json-buffer: 3.0.1 + klaw@3.0.0: + dependencies: + graceful-fs: 4.2.11 + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -2611,6 +2924,10 @@ snapshots: lilconfig@3.1.2: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + lint-staged@15.2.9: dependencies: chalk: 5.3.0 @@ -2678,10 +2995,30 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 9.0.0 + long@5.2.3: {} + magic-string@0.30.11: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + markdown-it-anchor@8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.0): + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + marked@4.3.0: {} + + mdurl@2.0.0: {} + memoize-one@6.0.0: {} merge-stream@2.0.0: {} @@ -2711,10 +3048,18 @@ snapshots: dependencies: brace-expansion: 1.1.11 + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 + minimist@1.2.8: {} + + mkdirp@1.0.4: {} + mlly@1.7.1: dependencies: acorn: 8.12.1 @@ -2756,6 +3101,15 @@ snapshots: dependencies: mimic-function: 5.0.1 + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -2822,6 +3176,8 @@ snapshots: preact@10.23.2: {} + prelude-ls@1.1.2: {} + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: @@ -2832,8 +3188,39 @@ snapshots: prismjs@1.29.0: {} + protobufjs-cli@1.1.3(protobufjs@7.4.0): + dependencies: + chalk: 4.1.2 + escodegen: 1.14.3 + espree: 9.6.1 + estraverse: 5.3.0 + glob: 8.1.0 + jsdoc: 4.0.3 + minimist: 1.2.8 + protobufjs: 7.4.0 + semver: 7.6.3 + tmp: 0.2.3 + uglify-js: 3.19.3 + + protobufjs@7.4.0: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 22.5.4 + long: 5.2.3 + proxy-from-env@1.1.0: {} + punycode.js@2.3.1: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -2844,6 +3231,10 @@ snapshots: regenerator-runtime@0.14.1: {} + requizzle@0.2.4: + dependencies: + lodash: 4.17.21 + resolve-from@4.0.0: {} restore-cursor@5.1.0: @@ -2932,6 +3323,9 @@ snapshots: source-map-js@1.2.0: {} + source-map@0.6.1: + optional: true + ssr-window@3.0.0: {} string-argv@0.3.2: {} @@ -2971,6 +3365,8 @@ snapshots: tiny-warning@1.0.3: {} + tmp@0.2.3: {} + to-fast-properties@2.0.0: {} to-regex-range@5.0.1: @@ -2979,6 +3375,10 @@ snapshots: tslib@2.6.3: {} + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -2987,8 +3387,16 @@ snapshots: type@2.7.3: {} + uc.micro@2.1.0: {} + ufo@1.5.4: {} + uglify-js@3.19.3: {} + + underscore@1.13.7: {} + + undici-types@6.19.8: {} + unimport@3.10.0(rollup@4.21.0): dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.21.0) @@ -3022,7 +3430,7 @@ snapshots: transitivePeerDependencies: - rollup - unplugin-vue-components@0.27.4(@babel/parser@7.25.3)(rollup@4.21.0)(vue@3.4.38): + unplugin-vue-components@0.27.4(@babel/parser@7.25.6)(rollup@4.21.0)(vue@3.4.38): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.0(rollup@4.21.0) @@ -3036,7 +3444,7 @@ snapshots: unplugin: 1.12.2 vue: 3.4.38 optionalDependencies: - '@babel/parser': 7.25.3 + '@babel/parser': 7.25.6 transitivePeerDependencies: - rollup - supports-color @@ -3056,12 +3464,13 @@ snapshots: uuid@10.0.0: {} - vite@5.4.1(sass@1.77.8): + vite@5.4.1(@types/node@22.5.4)(sass@1.77.8): dependencies: esbuild: 0.21.5 postcss: 8.4.41 rollup: 4.21.0 optionalDependencies: + '@types/node': 22.5.4 fsevents: 2.3.3 sass: 1.77.8 @@ -3117,6 +3526,8 @@ snapshots: xml-name-validator@4.0.0: {} + xmlcreate@2.0.4: {} + yaml@2.5.0: {} yocto-queue@0.1.0: {} diff --git a/src/api/wsConnect.js b/src/api/wsConnect.js new file mode 100644 index 0000000..1d46123 --- /dev/null +++ b/src/api/wsConnect.js @@ -0,0 +1,191 @@ +import { Msg, Header, MsgType } from '@/proto/msg' +import { MAGIC } from '@/const/msgConst' + +class WsConnect { + /** + * 单例 + */ + static instance = null + + /** + * WebSockt连接对象 + */ + connect + + /** + * 消息接收缓冲区 + */ + buffer + + constructor() { + const aar = [14, 10, 12, 8, 139, 150, 196, 240, 8, 16, 0, 24, 0] + this.buffer = new Uint8Array(aar) + } + + /** + * 单例 + */ + static getInstance() { + if (!WsConnect.instance) { + WsConnect.instance = new WsConnect() + } + return WsConnect.instance + } + + /** + * 相关配置 + */ + config = { + url: '', + account: '', + clientId: '', + token: '' + } + + /** + * 创建websocket + */ + createWs(account, clientId, token) { + this.config.url = `${import.meta.env.VITE_WS_URL}?token=${token}` + this.config.account = account + this.config.clientId = clientId + this.config.token = token + + this.connect = new WebSocket(this.config.url) + this.connect.onmessage = this.onMessage.bind(this) + this.connect.onclose = this.onClose.bind(this) + this.connect.onopen = this.onOpen.bind(this) + this.connect.onerror = this.onError.bind(this) + } + + async onMessage(evt) { + console.log('onMessage') + const arrayBuffer = await evt.data.arrayBuffer() + const frames = this.decode(new Uint8Array(arrayBuffer)) + + frames.forEach((frame) => { + const res = Msg.decode(frame) + console.log('Decoded res:', res) + }) + } + + onClose(evt) { + console.log('onClose', evt) + } + + onOpen() { + console.log('onOpen') + const header = Header.create({ + magic: MAGIC, + version: 0, + msgType: MsgType.HELLO, + isExtension: false + }) + const hello = Msg.create({ header: header }) + const payload = Msg.encode(hello).finish() + const data = this.encodePayload(payload) + console.log('encode data: ', data) + this.connect.send(data) + } + + onError(evt) { + console.log('onError', evt) + } + + /** + * 发送前对长度编码,配合服务端解决半包黏包问题 + * @param {*} payload + * @returns + */ + encodePayload(payload) { + let num = payload.length + let lenEncode = [] + while (num > 0) { + let byte = num & 0x7f + num >>= 7 + if (num > 0) { + byte |= 0x80 + } + lenEncode.push(byte) + } + return Uint8Array.of(...lenEncode, ...payload) + } + + /** + * 接收消息后对payload进行解码,剥离掉长度 + * @param {*} buf + * @returns + */ + decodePayload(buf) { + const view = new DataView(buf) + let byteIndex = 0 + + let length = 0 + let shift = 0 + // eslint-disable-next-line no-constant-condition + while (true) { + const byte = view.getUint8(byteIndex) + length |= (byte & 0x7f) << shift + byteIndex++ + if ((byte & 0x80) === 0) { + break + } + shift += 7 + } + + return new Uint8Array(buf, byteIndex, length) + } + + /** + * 数据解码,其中解决了半包黏包问题 + * @param {*} data + * @returns + */ + decode(data) { + this.buffer = this.concatBuffers(this.buffer, data) + + const frames = [] + // eslint-disable-next-line no-constant-condition + while (true) { + if (this.buffer.length < 1) { + break + } + + let length = 0 + let shift = 0 + let byteIndex = 0 + // eslint-disable-next-line no-constant-condition + while (true) { + if (byteIndex >= this.buffer.length) { + break + } + const byte = this.buffer[byteIndex] + length |= (byte & 0x7f) << shift + byteIndex++ + if ((byte & 0x80) === 0) { + break + } + shift += 7 + } + + if (this.buffer.length < byteIndex + length) { + break + } + + const frame = this.buffer.subarray(byteIndex, byteIndex + length) + frames.push(frame) + this.buffer = this.buffer.subarray(byteIndex + length) + } + + return frames + } + + concatBuffers(buffer1, buffer2) { + const newBuffer = new Uint8Array(buffer1.length + buffer2.length) + newBuffer.set(buffer1) + newBuffer.set(buffer2, buffer1.length) + return newBuffer + } +} + +export default WsConnect.getInstance() diff --git a/src/const/msgConst.js b/src/const/msgConst.js index 9f5da563..632f28e 100644 --- a/src/const/msgConst.js +++ b/src/const/msgConst.js @@ -2,3 +2,5 @@ export const msgType = { NO_MORE_MSG: 1, USER_MSG: 2 } + +export const MAGIC = 0x8e110b0b diff --git a/src/proto/msg.js b/src/proto/msg.js new file mode 100644 index 0000000..f0d2d46 --- /dev/null +++ b/src/proto/msg.js @@ -0,0 +1,1426 @@ +/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ +import * as $protobuf from 'protobufjs/minimal' + +// Common aliases +const $Reader = $protobuf.Reader, + $Writer = $protobuf.Writer, + $util = $protobuf.util + +// Exported root namespace +const $root = $protobuf.roots['default'] || ($protobuf.roots['default'] = {}) + +export const Msg = ($root.Msg = (() => { + /** + * Properties of a Msg. + * @exports IMsg + * @interface IMsg + * @property {IHeader|null} [header] Msg header + * @property {IBody|null} [body] Msg body + * @property {IExtension|null} [extension] Msg extension + */ + + /** + * Constructs a new Msg. + * @exports Msg + * @classdesc Represents a Msg. + * @implements IMsg + * @constructor + * @param {IMsg=} [properties] Properties to set + */ + function Msg(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]] + } + + /** + * Msg header. + * @member {IHeader|null|undefined} header + * @memberof Msg + * @instance + */ + Msg.prototype.header = null + + /** + * Msg body. + * @member {IBody|null|undefined} body + * @memberof Msg + * @instance + */ + Msg.prototype.body = null + + /** + * Msg extension. + * @member {IExtension|null|undefined} extension + * @memberof Msg + * @instance + */ + Msg.prototype.extension = null + + // OneOf field names bound to virtual getters and setters + let $oneOfFields + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Msg.prototype, '_extension', { + get: $util.oneOfGetter(($oneOfFields = ['extension'])), + set: $util.oneOfSetter($oneOfFields) + }) + + /** + * Creates a new Msg instance using the specified properties. + * @function create + * @memberof Msg + * @static + * @param {IMsg=} [properties] Properties to set + * @returns {Msg} Msg instance + */ + Msg.create = function create(properties) { + return new Msg(properties) + } + + /** + * Encodes the specified Msg message. Does not implicitly {@link Msg.verify|verify} messages. + * @function encode + * @memberof Msg + * @static + * @param {IMsg} message Msg message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Msg.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create() + if (message.header != null && Object.hasOwnProperty.call(message, 'header')) + $root.Header.encode(message.header, writer.uint32(/* id 1, wireType 2 =*/ 10).fork()).ldelim() + if (message.body != null && Object.hasOwnProperty.call(message, 'body')) + $root.Body.encode(message.body, writer.uint32(/* id 2, wireType 2 =*/ 18).fork()).ldelim() + if (message.extension != null && Object.hasOwnProperty.call(message, 'extension')) + $root.Extension.encode( + message.extension, + writer.uint32(/* id 99, wireType 2 =*/ 794).fork() + ).ldelim() + return writer + } + + /** + * Encodes the specified Msg message, length delimited. Does not implicitly {@link Msg.verify|verify} messages. + * @function encodeDelimited + * @memberof Msg + * @static + * @param {IMsg} message Msg message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Msg.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim() + } + + /** + * Decodes a Msg message from the specified reader or buffer. + * @function decode + * @memberof Msg + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {Msg} Msg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Msg.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader) + let end = length === undefined ? reader.len : reader.pos + length, + message = new $root.Msg() + while (reader.pos < end) { + let tag = reader.uint32() + switch (tag >>> 3) { + case 1: { + message.header = $root.Header.decode(reader, reader.uint32()) + break + } + case 2: { + message.body = $root.Body.decode(reader, reader.uint32()) + break + } + case 99: { + message.extension = $root.Extension.decode(reader, reader.uint32()) + break + } + default: + reader.skipType(tag & 7) + break + } + } + return message + } + + /** + * Decodes a Msg message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof Msg + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {Msg} Msg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Msg.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader) + return this.decode(reader, reader.uint32()) + } + + /** + * Verifies a Msg message. + * @function verify + * @memberof Msg + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Msg.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected' + let properties = {} + if (message.header != null && message.hasOwnProperty('header')) { + let error = $root.Header.verify(message.header) + if (error) return 'header.' + error + } + if (message.body != null && message.hasOwnProperty('body')) { + let error = $root.Body.verify(message.body) + if (error) return 'body.' + error + } + if (message.extension != null && message.hasOwnProperty('extension')) { + properties._extension = 1 + { + let error = $root.Extension.verify(message.extension) + if (error) return 'extension.' + error + } + } + return null + } + + /** + * Creates a Msg message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof Msg + * @static + * @param {Object.} object Plain object + * @returns {Msg} Msg + */ + Msg.fromObject = function fromObject(object) { + if (object instanceof $root.Msg) return object + let message = new $root.Msg() + if (object.header != null) { + if (typeof object.header !== 'object') throw TypeError('.Msg.header: object expected') + message.header = $root.Header.fromObject(object.header) + } + if (object.body != null) { + if (typeof object.body !== 'object') throw TypeError('.Msg.body: object expected') + message.body = $root.Body.fromObject(object.body) + } + if (object.extension != null) { + if (typeof object.extension !== 'object') throw TypeError('.Msg.extension: object expected') + message.extension = $root.Extension.fromObject(object.extension) + } + return message + } + + /** + * Creates a plain object from a Msg message. Also converts values to other types if specified. + * @function toObject + * @memberof Msg + * @static + * @param {Msg} message Msg + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Msg.toObject = function toObject(message, options) { + if (!options) options = {} + let object = {} + if (options.defaults) { + object.header = null + object.body = null + } + if (message.header != null && message.hasOwnProperty('header')) + object.header = $root.Header.toObject(message.header, options) + if (message.body != null && message.hasOwnProperty('body')) + object.body = $root.Body.toObject(message.body, options) + if (message.extension != null && message.hasOwnProperty('extension')) { + object.extension = $root.Extension.toObject(message.extension, options) + if (options.oneofs) object._extension = 'extension' + } + return object + } + + /** + * Converts this Msg to JSON. + * @function toJSON + * @memberof Msg + * @instance + * @returns {Object.} JSON object + */ + Msg.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions) + } + + /** + * Gets the default type url for Msg + * @function getTypeUrl + * @memberof Msg + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Msg.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com' + } + return typeUrlPrefix + '/Msg' + } + + return Msg +})()) + +/** + * MsgType enum. + * @exports MsgType + * @enum {number} + * @property {number} HELLO=0 HELLO value + * @property {number} HEART_BEAT=1 HEART_BEAT value + * @property {number} CHAT=2 CHAT value + * @property {number} GROUP_CHAT=3 GROUP_CHAT value + * @property {number} READ=4 READ value + * @property {number} DELIVERED=5 DELIVERED value + * @property {number} SENDER_SYNC=6 SENDER_SYNC value + * @property {number} CLOSE_BY_READ_IDLE=10 CLOSE_BY_READ_IDLE value + * @property {number} CLOSE_BY_ERROR_MAGIC=11 CLOSE_BY_ERROR_MAGIC value + * @property {number} DEFAULT=99 DEFAULT value + */ +export const MsgType = ($root.MsgType = (() => { + const valuesById = {}, + values = Object.create(valuesById) + values[(valuesById[0] = 'HELLO')] = 0 + values[(valuesById[1] = 'HEART_BEAT')] = 1 + values[(valuesById[2] = 'CHAT')] = 2 + values[(valuesById[3] = 'GROUP_CHAT')] = 3 + values[(valuesById[4] = 'READ')] = 4 + values[(valuesById[5] = 'DELIVERED')] = 5 + values[(valuesById[6] = 'SENDER_SYNC')] = 6 + values[(valuesById[10] = 'CLOSE_BY_READ_IDLE')] = 10 + values[(valuesById[11] = 'CLOSE_BY_ERROR_MAGIC')] = 11 + values[(valuesById[99] = 'DEFAULT')] = 99 + return values +})()) + +export const Header = ($root.Header = (() => { + /** + * Properties of a Header. + * @exports IHeader + * @interface IHeader + * @property {number|null} [magic] Header magic + * @property {number|null} [version] Header version + * @property {MsgType|null} [msgType] Header msgType + * @property {boolean|null} [isExtension] Header isExtension + */ + + /** + * Constructs a new Header. + * @exports Header + * @classdesc Represents a Header. + * @implements IHeader + * @constructor + * @param {IHeader=} [properties] Properties to set + */ + function Header(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]] + } + + /** + * Header magic. + * @member {number} magic + * @memberof Header + * @instance + */ + Header.prototype.magic = 0 + + /** + * Header version. + * @member {number} version + * @memberof Header + * @instance + */ + Header.prototype.version = 0 + + /** + * Header msgType. + * @member {MsgType} msgType + * @memberof Header + * @instance + */ + Header.prototype.msgType = 0 + + /** + * Header isExtension. + * @member {boolean} isExtension + * @memberof Header + * @instance + */ + Header.prototype.isExtension = false + + /** + * Creates a new Header instance using the specified properties. + * @function create + * @memberof Header + * @static + * @param {IHeader=} [properties] Properties to set + * @returns {Header} Header instance + */ + Header.create = function create(properties) { + return new Header(properties) + } + + /** + * Encodes the specified Header message. Does not implicitly {@link Header.verify|verify} messages. + * @function encode + * @memberof Header + * @static + * @param {IHeader} message Header message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Header.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create() + if (message.magic != null && Object.hasOwnProperty.call(message, 'magic')) + writer.uint32(/* id 1, wireType 0 =*/ 8).int32(message.magic) + if (message.version != null && Object.hasOwnProperty.call(message, 'version')) + writer.uint32(/* id 2, wireType 0 =*/ 16).int32(message.version) + if (message.msgType != null && Object.hasOwnProperty.call(message, 'msgType')) + writer.uint32(/* id 3, wireType 0 =*/ 24).int32(message.msgType) + if (message.isExtension != null && Object.hasOwnProperty.call(message, 'isExtension')) + writer.uint32(/* id 4, wireType 0 =*/ 32).bool(message.isExtension) + return writer + } + + /** + * Encodes the specified Header message, length delimited. Does not implicitly {@link Header.verify|verify} messages. + * @function encodeDelimited + * @memberof Header + * @static + * @param {IHeader} message Header message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Header.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim() + } + + /** + * Decodes a Header message from the specified reader or buffer. + * @function decode + * @memberof Header + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {Header} Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Header.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader) + let end = length === undefined ? reader.len : reader.pos + length, + message = new $root.Header() + while (reader.pos < end) { + let tag = reader.uint32() + switch (tag >>> 3) { + case 1: { + message.magic = reader.int32() + break + } + case 2: { + message.version = reader.int32() + break + } + case 3: { + message.msgType = reader.int32() + break + } + case 4: { + message.isExtension = reader.bool() + break + } + default: + reader.skipType(tag & 7) + break + } + } + return message + } + + /** + * Decodes a Header message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof Header + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {Header} Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Header.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader) + return this.decode(reader, reader.uint32()) + } + + /** + * Verifies a Header message. + * @function verify + * @memberof Header + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Header.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected' + if (message.magic != null && message.hasOwnProperty('magic')) + if (!$util.isInteger(message.magic)) return 'magic: integer expected' + if (message.version != null && message.hasOwnProperty('version')) + if (!$util.isInteger(message.version)) return 'version: integer expected' + if (message.msgType != null && message.hasOwnProperty('msgType')) + switch (message.msgType) { + default: + return 'msgType: enum value expected' + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 10: + case 11: + case 99: + break + } + if (message.isExtension != null && message.hasOwnProperty('isExtension')) + if (typeof message.isExtension !== 'boolean') return 'isExtension: boolean expected' + return null + } + + /** + * Creates a Header message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof Header + * @static + * @param {Object.} object Plain object + * @returns {Header} Header + */ + Header.fromObject = function fromObject(object) { + if (object instanceof $root.Header) return object + let message = new $root.Header() + if (object.magic != null) message.magic = object.magic | 0 + if (object.version != null) message.version = object.version | 0 + switch (object.msgType) { + default: + if (typeof object.msgType === 'number') { + message.msgType = object.msgType + break + } + break + case 'HELLO': + case 0: + message.msgType = 0 + break + case 'HEART_BEAT': + case 1: + message.msgType = 1 + break + case 'CHAT': + case 2: + message.msgType = 2 + break + case 'GROUP_CHAT': + case 3: + message.msgType = 3 + break + case 'READ': + case 4: + message.msgType = 4 + break + case 'DELIVERED': + case 5: + message.msgType = 5 + break + case 'SENDER_SYNC': + case 6: + message.msgType = 6 + break + case 'CLOSE_BY_READ_IDLE': + case 10: + message.msgType = 10 + break + case 'CLOSE_BY_ERROR_MAGIC': + case 11: + message.msgType = 11 + break + case 'DEFAULT': + case 99: + message.msgType = 99 + break + } + if (object.isExtension != null) message.isExtension = Boolean(object.isExtension) + return message + } + + /** + * Creates a plain object from a Header message. Also converts values to other types if specified. + * @function toObject + * @memberof Header + * @static + * @param {Header} message Header + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Header.toObject = function toObject(message, options) { + if (!options) options = {} + let object = {} + if (options.defaults) { + object.magic = 0 + object.version = 0 + object.msgType = options.enums === String ? 'HELLO' : 0 + object.isExtension = false + } + if (message.magic != null && message.hasOwnProperty('magic')) object.magic = message.magic + if (message.version != null && message.hasOwnProperty('version')) + object.version = message.version + if (message.msgType != null && message.hasOwnProperty('msgType')) + object.msgType = + options.enums === String + ? $root.MsgType[message.msgType] === undefined + ? message.msgType + : $root.MsgType[message.msgType] + : message.msgType + if (message.isExtension != null && message.hasOwnProperty('isExtension')) + object.isExtension = message.isExtension + return object + } + + /** + * Converts this Header to JSON. + * @function toJSON + * @memberof Header + * @instance + * @returns {Object.} JSON object + */ + Header.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions) + } + + /** + * Gets the default type url for Header + * @function getTypeUrl + * @memberof Header + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Header.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com' + } + return typeUrlPrefix + '/Header' + } + + return Header +})()) + +export const Body = ($root.Body = (() => { + /** + * Properties of a Body. + * @exports IBody + * @interface IBody + * @property {string|null} [fromId] Body fromId + * @property {string|null} [fromClient] Body fromClient + * @property {string|null} [toId] Body toId + * @property {string|null} [toClient] Body toClient + * @property {number|Long|null} [groupId] Body groupId + * @property {number|Long|null} [msgId] Body msgId + * @property {number|null} [seq] Body seq + * @property {number|null} [ack] Body ack + * @property {string|null} [content] Body content + * @property {string|null} [tempMsgId] Body tempMsgId + * @property {string|null} [sessionId] Body sessionId + */ + + /** + * Constructs a new Body. + * @exports Body + * @classdesc Represents a Body. + * @implements IBody + * @constructor + * @param {IBody=} [properties] Properties to set + */ + function Body(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]] + } + + /** + * Body fromId. + * @member {string|null|undefined} fromId + * @memberof Body + * @instance + */ + Body.prototype.fromId = null + + /** + * Body fromClient. + * @member {string|null|undefined} fromClient + * @memberof Body + * @instance + */ + Body.prototype.fromClient = null + + /** + * Body toId. + * @member {string|null|undefined} toId + * @memberof Body + * @instance + */ + Body.prototype.toId = null + + /** + * Body toClient. + * @member {string|null|undefined} toClient + * @memberof Body + * @instance + */ + Body.prototype.toClient = null + + /** + * Body groupId. + * @member {number|Long|null|undefined} groupId + * @memberof Body + * @instance + */ + Body.prototype.groupId = null + + /** + * Body msgId. + * @member {number|Long|null|undefined} msgId + * @memberof Body + * @instance + */ + Body.prototype.msgId = null + + /** + * Body seq. + * @member {number|null|undefined} seq + * @memberof Body + * @instance + */ + Body.prototype.seq = null + + /** + * Body ack. + * @member {number|null|undefined} ack + * @memberof Body + * @instance + */ + Body.prototype.ack = null + + /** + * Body content. + * @member {string|null|undefined} content + * @memberof Body + * @instance + */ + Body.prototype.content = null + + /** + * Body tempMsgId. + * @member {string|null|undefined} tempMsgId + * @memberof Body + * @instance + */ + Body.prototype.tempMsgId = null + + /** + * Body sessionId. + * @member {string|null|undefined} sessionId + * @memberof Body + * @instance + */ + Body.prototype.sessionId = null + + // OneOf field names bound to virtual getters and setters + let $oneOfFields + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_fromId', { + get: $util.oneOfGetter(($oneOfFields = ['fromId'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_fromClient', { + get: $util.oneOfGetter(($oneOfFields = ['fromClient'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_toId', { + get: $util.oneOfGetter(($oneOfFields = ['toId'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_toClient', { + get: $util.oneOfGetter(($oneOfFields = ['toClient'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_groupId', { + get: $util.oneOfGetter(($oneOfFields = ['groupId'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_msgId', { + get: $util.oneOfGetter(($oneOfFields = ['msgId'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_seq', { + get: $util.oneOfGetter(($oneOfFields = ['seq'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_ack', { + get: $util.oneOfGetter(($oneOfFields = ['ack'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_content', { + get: $util.oneOfGetter(($oneOfFields = ['content'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_tempMsgId', { + get: $util.oneOfGetter(($oneOfFields = ['tempMsgId'])), + set: $util.oneOfSetter($oneOfFields) + }) + + // Virtual OneOf for proto3 optional field + Object.defineProperty(Body.prototype, '_sessionId', { + get: $util.oneOfGetter(($oneOfFields = ['sessionId'])), + set: $util.oneOfSetter($oneOfFields) + }) + + /** + * Creates a new Body instance using the specified properties. + * @function create + * @memberof Body + * @static + * @param {IBody=} [properties] Properties to set + * @returns {Body} Body instance + */ + Body.create = function create(properties) { + return new Body(properties) + } + + /** + * Encodes the specified Body message. Does not implicitly {@link Body.verify|verify} messages. + * @function encode + * @memberof Body + * @static + * @param {IBody} message Body message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Body.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create() + if (message.fromId != null && Object.hasOwnProperty.call(message, 'fromId')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.fromId) + if (message.fromClient != null && Object.hasOwnProperty.call(message, 'fromClient')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.fromClient) + if (message.toId != null && Object.hasOwnProperty.call(message, 'toId')) + writer.uint32(/* id 3, wireType 2 =*/ 26).string(message.toId) + if (message.toClient != null && Object.hasOwnProperty.call(message, 'toClient')) + writer.uint32(/* id 4, wireType 2 =*/ 34).string(message.toClient) + if (message.groupId != null && Object.hasOwnProperty.call(message, 'groupId')) + writer.uint32(/* id 5, wireType 0 =*/ 40).int64(message.groupId) + if (message.msgId != null && Object.hasOwnProperty.call(message, 'msgId')) + writer.uint32(/* id 6, wireType 0 =*/ 48).int64(message.msgId) + if (message.seq != null && Object.hasOwnProperty.call(message, 'seq')) + writer.uint32(/* id 7, wireType 0 =*/ 56).int32(message.seq) + if (message.ack != null && Object.hasOwnProperty.call(message, 'ack')) + writer.uint32(/* id 8, wireType 0 =*/ 64).int32(message.ack) + if (message.content != null && Object.hasOwnProperty.call(message, 'content')) + writer.uint32(/* id 9, wireType 2 =*/ 74).string(message.content) + if (message.tempMsgId != null && Object.hasOwnProperty.call(message, 'tempMsgId')) + writer.uint32(/* id 10, wireType 2 =*/ 82).string(message.tempMsgId) + if (message.sessionId != null && Object.hasOwnProperty.call(message, 'sessionId')) + writer.uint32(/* id 11, wireType 2 =*/ 90).string(message.sessionId) + return writer + } + + /** + * Encodes the specified Body message, length delimited. Does not implicitly {@link Body.verify|verify} messages. + * @function encodeDelimited + * @memberof Body + * @static + * @param {IBody} message Body message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Body.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim() + } + + /** + * Decodes a Body message from the specified reader or buffer. + * @function decode + * @memberof Body + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {Body} Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Body.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader) + let end = length === undefined ? reader.len : reader.pos + length, + message = new $root.Body() + while (reader.pos < end) { + let tag = reader.uint32() + switch (tag >>> 3) { + case 1: { + message.fromId = reader.string() + break + } + case 2: { + message.fromClient = reader.string() + break + } + case 3: { + message.toId = reader.string() + break + } + case 4: { + message.toClient = reader.string() + break + } + case 5: { + message.groupId = reader.int64() + break + } + case 6: { + message.msgId = reader.int64() + break + } + case 7: { + message.seq = reader.int32() + break + } + case 8: { + message.ack = reader.int32() + break + } + case 9: { + message.content = reader.string() + break + } + case 10: { + message.tempMsgId = reader.string() + break + } + case 11: { + message.sessionId = reader.string() + break + } + default: + reader.skipType(tag & 7) + break + } + } + return message + } + + /** + * Decodes a Body message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof Body + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {Body} Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Body.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader) + return this.decode(reader, reader.uint32()) + } + + /** + * Verifies a Body message. + * @function verify + * @memberof Body + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Body.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected' + let properties = {} + if (message.fromId != null && message.hasOwnProperty('fromId')) { + properties._fromId = 1 + if (!$util.isString(message.fromId)) return 'fromId: string expected' + } + if (message.fromClient != null && message.hasOwnProperty('fromClient')) { + properties._fromClient = 1 + if (!$util.isString(message.fromClient)) return 'fromClient: string expected' + } + if (message.toId != null && message.hasOwnProperty('toId')) { + properties._toId = 1 + if (!$util.isString(message.toId)) return 'toId: string expected' + } + if (message.toClient != null && message.hasOwnProperty('toClient')) { + properties._toClient = 1 + if (!$util.isString(message.toClient)) return 'toClient: string expected' + } + if (message.groupId != null && message.hasOwnProperty('groupId')) { + properties._groupId = 1 + if ( + !$util.isInteger(message.groupId) && + !( + message.groupId && + $util.isInteger(message.groupId.low) && + $util.isInteger(message.groupId.high) + ) + ) + return 'groupId: integer|Long expected' + } + if (message.msgId != null && message.hasOwnProperty('msgId')) { + properties._msgId = 1 + if ( + !$util.isInteger(message.msgId) && + !( + message.msgId && + $util.isInteger(message.msgId.low) && + $util.isInteger(message.msgId.high) + ) + ) + return 'msgId: integer|Long expected' + } + if (message.seq != null && message.hasOwnProperty('seq')) { + properties._seq = 1 + if (!$util.isInteger(message.seq)) return 'seq: integer expected' + } + if (message.ack != null && message.hasOwnProperty('ack')) { + properties._ack = 1 + if (!$util.isInteger(message.ack)) return 'ack: integer expected' + } + if (message.content != null && message.hasOwnProperty('content')) { + properties._content = 1 + if (!$util.isString(message.content)) return 'content: string expected' + } + if (message.tempMsgId != null && message.hasOwnProperty('tempMsgId')) { + properties._tempMsgId = 1 + if (!$util.isString(message.tempMsgId)) return 'tempMsgId: string expected' + } + if (message.sessionId != null && message.hasOwnProperty('sessionId')) { + properties._sessionId = 1 + if (!$util.isString(message.sessionId)) return 'sessionId: string expected' + } + return null + } + + /** + * Creates a Body message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof Body + * @static + * @param {Object.} object Plain object + * @returns {Body} Body + */ + Body.fromObject = function fromObject(object) { + if (object instanceof $root.Body) return object + let message = new $root.Body() + if (object.fromId != null) message.fromId = String(object.fromId) + if (object.fromClient != null) message.fromClient = String(object.fromClient) + if (object.toId != null) message.toId = String(object.toId) + if (object.toClient != null) message.toClient = String(object.toClient) + if (object.groupId != null) + if ($util.Long) (message.groupId = $util.Long.fromValue(object.groupId)).unsigned = false + else if (typeof object.groupId === 'string') message.groupId = parseInt(object.groupId, 10) + else if (typeof object.groupId === 'number') message.groupId = object.groupId + else if (typeof object.groupId === 'object') + message.groupId = new $util.LongBits( + object.groupId.low >>> 0, + object.groupId.high >>> 0 + ).toNumber() + if (object.msgId != null) + if ($util.Long) (message.msgId = $util.Long.fromValue(object.msgId)).unsigned = false + else if (typeof object.msgId === 'string') message.msgId = parseInt(object.msgId, 10) + else if (typeof object.msgId === 'number') message.msgId = object.msgId + else if (typeof object.msgId === 'object') + message.msgId = new $util.LongBits( + object.msgId.low >>> 0, + object.msgId.high >>> 0 + ).toNumber() + if (object.seq != null) message.seq = object.seq | 0 + if (object.ack != null) message.ack = object.ack | 0 + if (object.content != null) message.content = String(object.content) + if (object.tempMsgId != null) message.tempMsgId = String(object.tempMsgId) + if (object.sessionId != null) message.sessionId = String(object.sessionId) + return message + } + + /** + * Creates a plain object from a Body message. Also converts values to other types if specified. + * @function toObject + * @memberof Body + * @static + * @param {Body} message Body + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Body.toObject = function toObject(message, options) { + if (!options) options = {} + let object = {} + if (message.fromId != null && message.hasOwnProperty('fromId')) { + object.fromId = message.fromId + if (options.oneofs) object._fromId = 'fromId' + } + if (message.fromClient != null && message.hasOwnProperty('fromClient')) { + object.fromClient = message.fromClient + if (options.oneofs) object._fromClient = 'fromClient' + } + if (message.toId != null && message.hasOwnProperty('toId')) { + object.toId = message.toId + if (options.oneofs) object._toId = 'toId' + } + if (message.toClient != null && message.hasOwnProperty('toClient')) { + object.toClient = message.toClient + if (options.oneofs) object._toClient = 'toClient' + } + if (message.groupId != null && message.hasOwnProperty('groupId')) { + if (typeof message.groupId === 'number') + object.groupId = options.longs === String ? String(message.groupId) : message.groupId + else + object.groupId = + options.longs === String + ? $util.Long.prototype.toString.call(message.groupId) + : options.longs === Number + ? new $util.LongBits(message.groupId.low >>> 0, message.groupId.high >>> 0).toNumber() + : message.groupId + if (options.oneofs) object._groupId = 'groupId' + } + if (message.msgId != null && message.hasOwnProperty('msgId')) { + if (typeof message.msgId === 'number') + object.msgId = options.longs === String ? String(message.msgId) : message.msgId + else + object.msgId = + options.longs === String + ? $util.Long.prototype.toString.call(message.msgId) + : options.longs === Number + ? new $util.LongBits(message.msgId.low >>> 0, message.msgId.high >>> 0).toNumber() + : message.msgId + if (options.oneofs) object._msgId = 'msgId' + } + if (message.seq != null && message.hasOwnProperty('seq')) { + object.seq = message.seq + if (options.oneofs) object._seq = 'seq' + } + if (message.ack != null && message.hasOwnProperty('ack')) { + object.ack = message.ack + if (options.oneofs) object._ack = 'ack' + } + if (message.content != null && message.hasOwnProperty('content')) { + object.content = message.content + if (options.oneofs) object._content = 'content' + } + if (message.tempMsgId != null && message.hasOwnProperty('tempMsgId')) { + object.tempMsgId = message.tempMsgId + if (options.oneofs) object._tempMsgId = 'tempMsgId' + } + if (message.sessionId != null && message.hasOwnProperty('sessionId')) { + object.sessionId = message.sessionId + if (options.oneofs) object._sessionId = 'sessionId' + } + return object + } + + /** + * Converts this Body to JSON. + * @function toJSON + * @memberof Body + * @instance + * @returns {Object.} JSON object + */ + Body.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions) + } + + /** + * Gets the default type url for Body + * @function getTypeUrl + * @memberof Body + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Body.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com' + } + return typeUrlPrefix + '/Body' + } + + return Body +})()) + +export const Extension = ($root.Extension = (() => { + /** + * Properties of an Extension. + * @exports IExtension + * @interface IExtension + * @property {Object.|null} [extensionMap] Extension extensionMap + */ + + /** + * Constructs a new Extension. + * @exports Extension + * @classdesc Represents an Extension. + * @implements IExtension + * @constructor + * @param {IExtension=} [properties] Properties to set + */ + function Extension(properties) { + this.extensionMap = {} + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]] + } + + /** + * Extension extensionMap. + * @member {Object.} extensionMap + * @memberof Extension + * @instance + */ + Extension.prototype.extensionMap = $util.emptyObject + + /** + * Creates a new Extension instance using the specified properties. + * @function create + * @memberof Extension + * @static + * @param {IExtension=} [properties] Properties to set + * @returns {Extension} Extension instance + */ + Extension.create = function create(properties) { + return new Extension(properties) + } + + /** + * Encodes the specified Extension message. Does not implicitly {@link Extension.verify|verify} messages. + * @function encode + * @memberof Extension + * @static + * @param {IExtension} message Extension message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Extension.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create() + if (message.extensionMap != null && Object.hasOwnProperty.call(message, 'extensionMap')) + for (let keys = Object.keys(message.extensionMap), i = 0; i < keys.length; ++i) + writer + .uint32(/* id 1, wireType 2 =*/ 10) + .fork() + .uint32(/* id 1, wireType 2 =*/ 10) + .string(keys[i]) + .uint32(/* id 2, wireType 2 =*/ 18) + .string(message.extensionMap[keys[i]]) + .ldelim() + return writer + } + + /** + * Encodes the specified Extension message, length delimited. Does not implicitly {@link Extension.verify|verify} messages. + * @function encodeDelimited + * @memberof Extension + * @static + * @param {IExtension} message Extension message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Extension.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim() + } + + /** + * Decodes an Extension message from the specified reader or buffer. + * @function decode + * @memberof Extension + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {Extension} Extension + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Extension.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader) + let end = length === undefined ? reader.len : reader.pos + length, + message = new $root.Extension(), + key, + value + while (reader.pos < end) { + let tag = reader.uint32() + switch (tag >>> 3) { + case 1: { + if (message.extensionMap === $util.emptyObject) message.extensionMap = {} + let end2 = reader.uint32() + reader.pos + key = '' + value = '' + while (reader.pos < end2) { + let tag2 = reader.uint32() + switch (tag2 >>> 3) { + case 1: + key = reader.string() + break + case 2: + value = reader.string() + break + default: + reader.skipType(tag2 & 7) + break + } + } + message.extensionMap[key] = value + break + } + default: + reader.skipType(tag & 7) + break + } + } + return message + } + + /** + * Decodes an Extension message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof Extension + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {Extension} Extension + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Extension.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader) + return this.decode(reader, reader.uint32()) + } + + /** + * Verifies an Extension message. + * @function verify + * @memberof Extension + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Extension.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected' + if (message.extensionMap != null && message.hasOwnProperty('extensionMap')) { + if (!$util.isObject(message.extensionMap)) return 'extensionMap: object expected' + let key = Object.keys(message.extensionMap) + for (let i = 0; i < key.length; ++i) + if (!$util.isString(message.extensionMap[key[i]])) + return 'extensionMap: string{k:string} expected' + } + return null + } + + /** + * Creates an Extension message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof Extension + * @static + * @param {Object.} object Plain object + * @returns {Extension} Extension + */ + Extension.fromObject = function fromObject(object) { + if (object instanceof $root.Extension) return object + let message = new $root.Extension() + if (object.extensionMap) { + if (typeof object.extensionMap !== 'object') + throw TypeError('.Extension.extensionMap: object expected') + message.extensionMap = {} + for (let keys = Object.keys(object.extensionMap), i = 0; i < keys.length; ++i) + message.extensionMap[keys[i]] = String(object.extensionMap[keys[i]]) + } + return message + } + + /** + * Creates a plain object from an Extension message. Also converts values to other types if specified. + * @function toObject + * @memberof Extension + * @static + * @param {Extension} message Extension + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Extension.toObject = function toObject(message, options) { + if (!options) options = {} + let object = {} + if (options.objects || options.defaults) object.extensionMap = {} + let keys2 + if (message.extensionMap && (keys2 = Object.keys(message.extensionMap)).length) { + object.extensionMap = {} + for (let j = 0; j < keys2.length; ++j) + object.extensionMap[keys2[j]] = message.extensionMap[keys2[j]] + } + return object + } + + /** + * Converts this Extension to JSON. + * @function toJSON + * @memberof Extension + * @instance + * @returns {Object.} JSON object + */ + Extension.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions) + } + + /** + * Gets the default type url for Extension + * @function getTypeUrl + * @memberof Extension + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Extension.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com' + } + return typeUrlPrefix + '/Extension' + } + + return Extension +})()) + +export { $root as default } diff --git a/src/proto/msg.proto b/src/proto/msg.proto new file mode 100644 index 0000000..1843f77 --- /dev/null +++ b/src/proto/msg.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +message Msg { + Header header = 1; + Body body = 2; + optional Extension extension = 99; +} + +enum MsgType { + HELLO = 0; //握手 + HEART_BEAT = 1; //心跳 + CHAT = 2; //单聊 + GROUP_CHAT = 3; //群聊 + READ = 4; // 已读 + DELIVERED = 5; //已发送 + SENDER_SYNC = 6; //发送端多设备之间同步的消息 + + CLOSE_BY_READ_IDLE = 10; //超时关闭 + CLOSE_BY_ERROR_MAGIC = 11; //magic不对关闭 + + DEFAULT = 99; +} + +message Header { + int32 magic = 1; + int32 version = 2; + MsgType msgType = 3; + bool isExtension = 4; +} + +message Body { + optional string fromId = 1; + optional string fromClient = 2; + optional string toId = 3; + optional string toClient = 4; + optional int64 groupId = 5; + optional int64 msgId = 6; + optional int32 seq = 7; + optional int32 ack = 8; + optional string content = 9; + optional string tempMsgId = 10; //客户端生成的临时msgId,不能用于消息排序,所以必须照服务端换正式的msgId + optional string sessionId = 11; //MsgType=SENDER_SYNC需带上该字段,因为此时fromId和toId都是发送端的账号,无法识别是哪个session +} + +message Extension { + map extensionMap = 1; +} diff --git a/src/router/index.js b/src/router/index.js index 73906bb..158b6b4 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -53,23 +53,28 @@ const router = createRouter({ router.beforeEach((to, from, next) => { const userData = userStore() + console.log(111) // 如果没有access token,且访问的是非登录页,拦截到登录 if (!userData.at.token && to.path !== '/login') { + console.log(222) next('/login') return } // 如果有access token,且访问的是登录页,拦截到首页 if (userData.at.token && to.path === '/login') { + console.log(333) next('/') return } // 检查是否是其他请求(除了已定义的路由之外的请求) if (!router.getRoutes().some((route) => route.path === to.path)) { + console.log(444) next('/') } else { + console.log(555) next() } }) diff --git a/src/views/LoginPage.vue b/src/views/LoginPage.vue index a8e5e20..97aafe5 100644 --- a/src/views/LoginPage.vue +++ b/src/views/LoginPage.vue @@ -5,6 +5,7 @@ import router from '@/router' import { userRegisterService, userLoginService } from '@/api/user.js' import { userStore } from '@/stores' import { generateClientId } from '@/utils/common' +import wsConnect from '@/api/wsConnect' const isRegister = ref(false) @@ -75,6 +76,7 @@ const login = async () => { userData.setRt(res.data.data.refreshToken) userData.setIsRemenberMe(isRemenberMe.value) await userData.getUser() //这里要用await确保拿到结果了再跳转,否则其他页面依赖user的不能及时得到更新 + wsConnect.createWs(userData.user.account, userData.clientId, userData.at.token) router.push('/') }) .catch(() => {