mpaas-jsapi-proxy 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -3
- package/package.json +1 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var b=Object.create,v=Object.defineProperty,
|
|
1
|
+
var b=Object.create,v=Object.defineProperty,m=Object.getOwnPropertyDescriptor,w=Object.getOwnPropertyNames,S=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty,_=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(var n=w(t),l=0,o=n.length,i;l<o;l++)i=n[l],!D.call(e,i)&&i!==r&&v(e,i,{get:(I=>t[I]).bind(null,i),enumerable:!(s=m(t,i))||s.enumerable});return e},p=(e,t,r)=>(r=e!=null?b(S(e)):{},_(t||!e||!e.__esModule?v(r,"default",{value:e,enumerable:!0}):r,e));let C=require("ws"),h=require("qrcode-terminal");h=p(h);let d=require("os");d=p(d);let g=require("minimist");g=p(g);var a=class{static getLocalIP(){const e=d.default.networkInterfaces();for(const t of Object.keys(e))for(const r of e[t])if(r.family==="IPv4"&&!r.internal)return r.address;return"localhost"}static formatServerUrl(e,t,r){return`ws://${e}:${t}${r}`}static log(e,t="info"){const r=new Date().toLocaleTimeString("zh-CN");console.log(`[${r}] ${{info:"ℹ️",success:"✅",error:"❌",warn:"⚠️"}[t]||"ℹ️"} ${e}`)}},y=class{constructor(){this.devices=new Map}registerDevice(e,t,r){if(this.devices.has(e)){const s=this.devices.get(e);s.ws=t,s.deviceInfo=r,s.lastHeartbeat=Date.now(),a.log(`设备更新连接: ${e}`,"info")}else this.devices.set(e,{ws:t,simulatorWS:null,deviceInfo:r,lastHeartbeat:Date.now()}),a.log(`设备注册成功: ${e}`,"success")}disconnect(e){for(const[t,r]of this.devices)if(r.ws===e)return this.devices.delete(t),a.log(`设备断开连接: ${t}`,"warn"),!0;return!1}getDevice(e){return this.devices.get(e)}isDeviceReady(e){const t=this.devices.get(e);return!!t&&!!t.ws}updateHeartbeat(e){const t=this.devices.get(e);t&&(t.lastHeartbeat=Date.now())}getAllDevices(){return Array.from(this.devices.entries()).map(([e,t])=>({deviceId:e,hasMiniapp:!!t.ws,lastHeartbeat:t.lastHeartbeat}))}get devicesMap(){return this.devices}},P=class{constructor(e){this.httpServer=null,this.deviceManager=e,this.pendingCalls=new Map}setHttpServer(e){this.httpServer=e}handleMessage(e,t){const{type:r,msgId:s,deviceId:n}=e;if(!r||!s){this.sendError(t,s,"INVALID_MESSAGE","消息格式错误");return}switch(r){case"client_call":this.handleClientCall(e,t);break;case"register":this.handleRegister(e,t);break;case"response":this.handleResponse(e,t);break;case"heartbeat":this.handleHeartbeat(e);break;default:this.sendError(t,s,"UNKNOWN_MESSAGE_TYPE",`未知消息类型: ${r}`)}}handleRegister(e,t){const{msgId:r,deviceId:s,deviceInfo:n}=e;if(!s){this.sendError(t,r,"INVALID_DEVICE_ID","设备ID不能为空");return}this.deviceManager.registerDevice(s,t,n||{}),t.send(JSON.stringify({type:"register",msgId:r,deviceId:s,success:!0,timestamp:Date.now()}))}handleClientCall(e,t){const{msgId:r,deviceId:s,api:n,params:l}=e;if(!s){this.sendError(t,r,"INVALID_DEVICE_ID","设备ID不能为空");return}this.pendingCalls.set(r,{ws:t,deviceId:s,timestamp:Date.now()});const o=this.deviceManager.getDevice(s);if(!o||!o.ws){this.pendingCalls.delete(r),this.sendError(t,r,"DEVICE_OFFLINE","代理小程序未连接");return}try{o.ws.send(JSON.stringify(e)),a.log(`转发调用: ${n} → ${s} -> ${r}`,"info")}catch(i){this.pendingCalls.delete(r),this.sendError(t,r,"SEND_FAILED",`发送失败: ${i.message}`)}}handleResponse(e,t){const{msgId:r}=e,s=this.pendingCalls.get(r);if(!s){a.log(`未找到对应的请求: ${r}`,"warn");return}a.log(`转发响应 → msgId: ${r}`,"info");try{s.ws.send(JSON.stringify(e))}catch(n){a.log(`转发响应失败: ${n.message}`,"error")}finally{this.pendingCalls.delete(r)}}handleHeartbeat(e){const{deviceId:t}=e;t&&this.deviceManager.updateHeartbeat(t)}sendError(e,t,r,s){e&&e.readyState===1&&e.send(JSON.stringify({type:"error",msgId:t,timestamp:Date.now(),error:{code:r,message:s}}))}clearPendingCallsForWS(e){for(const[t,r]of this.pendingCalls)r.ws===e&&this.pendingCalls.delete(t)}},f={port:7521,wsPath:"/ws",heartbeatInterval:3e4,appId:"2026052614145188"},E=class{constructor(e){const t={port:3e3,wsPath:"/ws",heartbeatInterval:3e4};this.config={...t,...e},this.deviceManager=new y,this.messageRouter=new P(this.deviceManager),this.wss=null,this.heartbeatTimer=null}start(){this.wss=new C.WebSocketServer({port:this.config.port,path:this.config.wsPath}),this.wss.on("connection",(e,t)=>{this.handleConnection(e,t)}),this.wss.on("error",e=>{a.log(`服务器错误: ${e.message}`,"error")}),this.startHeartbeatCheck(),a.log("代理服务器启动成功","success"),a.log(`监听端口: ${this.config.port}`,"info"),this.displayConnectionInfo()}handleConnection(e,t){const r=new URL(t.url,`http://${t.headers.host}`).searchParams.get("type");a.log(`新连接: ${r||"unknown"}`,"info"),e.on("message",s=>{try{const n=JSON.parse(s.toString());this.messageRouter.handleMessage(n,e)}catch(n){a.log(`消息解析失败: ${n.message}`,"error")}}),e.on("close",()=>{this.deviceManager.disconnect(e),this.messageRouter.clearPendingCallsForWS(e)}),e.on("error",s=>{a.log(`WebSocket错误: ${s.message}`,"error")})}displayConnectionInfo(){const e=a.getLocalIP(),t=a.formatServerUrl(e,this.config.port,"");console.log(`
|
|
2
2
|
╔════════════════════════════════════════════════════════════╗
|
|
3
3
|
║ mPaaS JSAPI 代理服务器 ║
|
|
4
4
|
╠════════════════════════════════════════════════════════════╣
|
|
@@ -8,5 +8,5 @@ var b=Object.create,v=Object.defineProperty,I=Object.getOwnPropertyDescriptor,m=
|
|
|
8
8
|
║ ║
|
|
9
9
|
║ 或扫描下方二维码快速配置: ║
|
|
10
10
|
╚════════════════════════════════════════════════════════════╝
|
|
11
|
-
`),console.log("");const r=`url=${encodeURIComponent(t)}`;h.default.generate(r,{small:!0})}startHeartbeatCheck(){this.heartbeatTimer=setInterval(()=>{const e=Date.now(),t=this.config.heartbeatInterval*2;for(const[r,s]of this.deviceManager.devicesMap)e-s.lastHeartbeat>t&&(a.log(`设备心跳超时: ${r}`,"warn"),s.ws&&s.ws.close(),s.simulatorWS&&s.simulatorWS.close(),this.deviceManager.devicesMap.delete(r))},this.config.heartbeatInterval)}stop(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null),this.wss&&(this.wss.close(),a.log("服务器已关闭","info"))}},
|
|
12
|
-
正在关闭服务器...`),
|
|
11
|
+
`),console.log("");const r=`xlmpaas://${f.appId}?url=${encodeURIComponent(t)}`;h.default.generate(r,{small:!0})}startHeartbeatCheck(){this.heartbeatTimer=setInterval(()=>{const e=Date.now(),t=this.config.heartbeatInterval*2;for(const[r,s]of this.deviceManager.devicesMap)e-s.lastHeartbeat>t&&(a.log(`设备心跳超时: ${r}`,"warn"),s.ws&&s.ws.close(),s.simulatorWS&&s.simulatorWS.close(),this.deviceManager.devicesMap.delete(r))},this.config.heartbeatInterval)}stop(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null),this.wss&&(this.wss.close(),a.log("服务器已关闭","info"))}},c=(0,g.default)(process.argv.slice(2)),u=new E({...f,...c.p!==void 0&&{port:Number(c.p)},...c.port!==void 0&&{port:Number(c.port)}});u.start();process.on("SIGINT",()=>{console.log(`
|
|
12
|
+
正在关闭服务器...`),u.stop(),process.exit(0)});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mpaas-jsapi-proxy",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "mPaaS JSAPI 代理服务器",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"start": "node dist/index.js",
|
|
15
15
|
"dev": "tsx watch src/index.ts",
|
|
16
16
|
"build": "vite build",
|
|
17
|
-
"prepublishOnly": "npm run build",
|
|
18
17
|
"type-check": "tsc --noEmit"
|
|
19
18
|
},
|
|
20
19
|
"keywords": [
|