@pixelhue/event-controller-sdk 0.0.1 → 0.0.14
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.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/packages/tcp/ConnectManager.d.ts +1 -2
- package/dist/packages/tcp/ConnectManager.js +2 -3
- package/dist/packages/tcp/QueueManager.d.ts +0 -1
- package/dist/packages/tcp/QueueManager.js +9 -14
- package/dist/packages/tcp/SocketWrapper.d.ts +13 -3
- package/dist/packages/tcp/SocketWrapper.js +68 -28
- package/dist/packages/tcp/constants.d.ts +0 -1
- package/dist/packages/tcp/constants.js +0 -1
- package/dist/packages/tcp/discoveryService.d.ts +0 -1
- package/dist/packages/tcp/discoveryService.js +0 -1
- package/dist/packages/tcp/protocolHandler.d.ts +0 -1
- package/dist/packages/tcp/protocolHandler.js +2 -2
- package/dist/packages/tcp/tcpWrapper.d.ts +27 -4
- package/dist/packages/tcp/tcpWrapper.js +106 -50
- package/dist/packages/tcp/types.d.ts +0 -1
- package/dist/packages/tcp/types.js +0 -1
- package/dist/packages/tcp/utils.d.ts +0 -1
- package/dist/packages/tcp/utils.js +0 -1
- package/package.json +87 -82
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/packages/tcp/ConnectManager.d.ts.map +0 -1
- package/dist/packages/tcp/ConnectManager.js.map +0 -1
- package/dist/packages/tcp/QueueManager.d.ts.map +0 -1
- package/dist/packages/tcp/QueueManager.js.map +0 -1
- package/dist/packages/tcp/SocketWrapper.d.ts.map +0 -1
- package/dist/packages/tcp/SocketWrapper.js.map +0 -1
- package/dist/packages/tcp/constants.d.ts.map +0 -1
- package/dist/packages/tcp/constants.js.map +0 -1
- package/dist/packages/tcp/demo.d.ts +0 -3
- package/dist/packages/tcp/demo.d.ts.map +0 -1
- package/dist/packages/tcp/demo.js +0 -164
- package/dist/packages/tcp/demo.js.map +0 -1
- package/dist/packages/tcp/discoveryService.d.ts.map +0 -1
- package/dist/packages/tcp/discoveryService.js.map +0 -1
- package/dist/packages/tcp/protocolHandler.d.ts.map +0 -1
- package/dist/packages/tcp/protocolHandler.js.map +0 -1
- package/dist/packages/tcp/tcpWrapper.d.ts.map +0 -1
- package/dist/packages/tcp/tcpWrapper.js.map +0 -1
- package/dist/packages/tcp/test-build-parse-debug.d.ts +0 -2
- package/dist/packages/tcp/test-build-parse-debug.d.ts.map +0 -1
- package/dist/packages/tcp/test-build-parse-debug.js +0 -73
- package/dist/packages/tcp/test-build-parse-debug.js.map +0 -1
- package/dist/packages/tcp/test-packet-split.d.ts +0 -43
- package/dist/packages/tcp/test-packet-split.d.ts.map +0 -1
- package/dist/packages/tcp/test-packet-split.js +0 -417
- package/dist/packages/tcp/test-packet-split.js.map +0 -1
- package/dist/packages/tcp/test-protocol-handler.d.ts +0 -6
- package/dist/packages/tcp/test-protocol-handler.d.ts.map +0 -1
- package/dist/packages/tcp/test-protocol-handler.js +0 -225
- package/dist/packages/tcp/test-protocol-handler.js.map +0 -1
- package/dist/packages/tcp/test-server.d.ts +0 -54
- package/dist/packages/tcp/test-server.d.ts.map +0 -1
- package/dist/packages/tcp/test-server.js +0 -412
- package/dist/packages/tcp/test-server.js.map +0 -1
- package/dist/packages/tcp/types.d.ts.map +0 -1
- package/dist/packages/tcp/types.js.map +0 -1
- package/dist/packages/tcp/utils.d.ts.map +0 -1
- package/dist/packages/tcp/utils.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,82 +1,87 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@pixelhue/event-controller-sdk",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Node service for PixelHue Event Controller device",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"build": "tsc",
|
|
10
|
-
"dev": "tsc --watch",
|
|
11
|
-
"start": "node dist/index.js",
|
|
12
|
-
"start:dev": "tsx src/index.ts",
|
|
13
|
-
"test": "jest",
|
|
14
|
-
"test:watch": "jest --watch",
|
|
15
|
-
"test:coverage": "jest --coverage",
|
|
16
|
-
"lint": "
|
|
17
|
-
"lint:
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"@
|
|
59
|
-
"@
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"eslint": "^
|
|
63
|
-
"eslint
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"eslint
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@pixelhue/event-controller-sdk",
|
|
3
|
+
"version": "0.0.14",
|
|
4
|
+
"description": "Node service for PixelHue Event Controller device",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"dev": "tsc --watch",
|
|
11
|
+
"start": "node dist/index.js",
|
|
12
|
+
"start:dev": "tsx src/index.ts",
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"test:watch": "jest --watch",
|
|
15
|
+
"test:coverage": "jest --coverage",
|
|
16
|
+
"lint-staged": "lint-staged",
|
|
17
|
+
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
|
|
18
|
+
"lint:prettier": "prettier -c --write \"src/**/*\" --end-of-line auto",
|
|
19
|
+
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx ./src",
|
|
20
|
+
"lint": "npm run lint:js && npm run lint:prettier",
|
|
21
|
+
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx ./src",
|
|
22
|
+
"prettier": "prettier -c --write \"src/**/*\"",
|
|
23
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
24
|
+
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
25
|
+
"commit": "cz",
|
|
26
|
+
"prepare": "husky",
|
|
27
|
+
"mock:device": "node pixelhue-mock-device.js",
|
|
28
|
+
"changelog": "standard-version -a -n -r patch",
|
|
29
|
+
"changelog:minor": "standard-version -a -n -r minor",
|
|
30
|
+
"changelog:major": "standard-version -a -n -r major",
|
|
31
|
+
"release": "yarn run changelog && yarn run build && npm publish"
|
|
32
|
+
},
|
|
33
|
+
"config": {
|
|
34
|
+
"commitizen": {
|
|
35
|
+
"path": "cz-customizable"
|
|
36
|
+
},
|
|
37
|
+
"cz-customizable": {
|
|
38
|
+
"config": "./.cz-config.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"pixelhue",
|
|
43
|
+
"event-controller",
|
|
44
|
+
"u5-mini",
|
|
45
|
+
"device",
|
|
46
|
+
"service"
|
|
47
|
+
],
|
|
48
|
+
"author": "",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"registry": "https://registry.npmjs.org/",
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"files": [
|
|
55
|
+
"dist"
|
|
56
|
+
],
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@commitlint/cli": "^18.6.0",
|
|
59
|
+
"@commitlint/config-conventional": "^18.6.0",
|
|
60
|
+
"@types/jest": "^29.5.11",
|
|
61
|
+
"@types/node": "^20.11.0",
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
63
|
+
"@typescript-eslint/parser": "^6.19.0",
|
|
64
|
+
"commitizen": "^4.3.0",
|
|
65
|
+
"cz-customizable": "^7.0.0",
|
|
66
|
+
"eslint": "^8.56.0",
|
|
67
|
+
"eslint-config-prettier": "^9.1.0",
|
|
68
|
+
"eslint-import-resolver-typescript": "^3.6.1",
|
|
69
|
+
"eslint-plugin-babel": "^5.3.1",
|
|
70
|
+
"eslint-plugin-import": "^2.29.1",
|
|
71
|
+
"eslint-plugin-simple-import-sort": "^12.0.0",
|
|
72
|
+
"husky": "^9.0.10",
|
|
73
|
+
"jest": "^29.7.0",
|
|
74
|
+
"prettier": "^3.2.4",
|
|
75
|
+
"standard-version": "^9.3.1",
|
|
76
|
+
"ts-jest": "^29.1.2",
|
|
77
|
+
"tsx": "^4.7.0",
|
|
78
|
+
"typescript": "^5.3.3"
|
|
79
|
+
},
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"@julusian/bonjour-service": "^1.4.2",
|
|
82
|
+
"@unico/uniform-protocol-builder": "^1.0.0",
|
|
83
|
+
"@unico/uniform-protocol-parser": "^1.0.0",
|
|
84
|
+
"eventemitter3": "^5.0.1",
|
|
85
|
+
"p-queue": "^9.0.0"
|
|
86
|
+
}
|
|
87
|
+
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAG1D,YAAY,EACX,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,uBAAuB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,0BAA0B,EAC1B,yBAAyB,EACzB,8BAA8B,EAC9B,kCAAkC,EAClC,2BAA2B,EAC3B,8BAA8B,GAC9B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAG/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,QAAQ;AACR,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAuB1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO;AACP,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,0BAA0B,EAC1B,yBAAyB,EACzB,8BAA8B,EAC9B,kCAAkC,EAClC,2BAA2B,EAC3B,8BAA8B,GAC9B,MAAM,6BAA6B,CAAC;AAErC,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["/**\r\n * PixelHue U5 Mini Event Controller SDK\r\n *\r\n * 提供 PixelHue U5 Mini 设备的连接管理、设备发现、协议处理等功能\r\n */\r\n\r\n// 主要类导出\r\nexport { MiniConnectionManager } from './packages/tcp/ConnectManager.js';\r\nexport { MiniDiscoveryService } from './packages/tcp/discoveryService.js';\r\nexport { ProtocolHandler } from './packages/tcp/protocolHandler.js';\r\nexport { QueueManager, DEFAULT_QUEUE_OPTIONS } from './packages/tcp/QueueManager.js';\r\nexport { SocketWrapper } from './packages/tcp/SocketWrapper.js';\r\nexport { TcpWrapper } from './packages/tcp/tcpWrapper.js';\r\n\r\n// 类型导出\r\nexport type {\r\n\tSocketConnectOptions,\r\n\tQueueOptions,\r\n\tQueueMetrics,\r\n\tProtocolHandlerOptions,\r\n\tProtocolSendPayload,\r\n\tSocketWrapperEvents,\r\n\tISocketWrapper,\r\n\tResponseQueueItem,\r\n\tSocketWrapperInstance,\r\n\tRequestIdExtractor,\r\n\tHeartbeatBuilder,\r\n\tHeartbeatResponseChecker,\r\n\tConnectionManagerEvents,\r\n\tDiscoveryEvents,\r\n\tMiniDeviceInfo,\r\n\tMiniDiscoveredDevice,\r\n\tDiscoveryServiceOptions,\r\n} from './packages/tcp/types.js';\r\n\r\nexport { QueueOverflowStrategy } from './packages/tcp/types.js';\r\n\r\n// 常量导出\r\nexport {\r\n\tSUPPORTED_MODELS,\r\n\tDEFAULT_TCP_PORT,\r\n\tDEFAULT_ENABLE_HEARTBEAT,\r\n\tDEFAULT_AUTO_RECONNECT,\r\n\tDEFAULT_HEARTBEAT_INTERVAL,\r\n\tDEFAULT_RECONNECT_INTERVAL,\r\n\tDEFAULT_HEARTBEAT_TIMEOUT,\r\n\tDEFAULT_MAX_RECONNECT_INTERVAL,\r\n\tDEFAULT_ENABLE_EXPONENTIAL_BACKOFF,\r\n\tDEFAULT_MDNS_QUERY_INTERVAL,\r\n\tDEFAULT_MAX_RECONNECT_ATTEMPTS,\r\n} from './packages/tcp/constants.js';\r\n\r\n// 工具函数导出\r\nexport { parseHost, parsePort } from './packages/tcp/utils.js';\r\n\r\n// 协议处理结果类型导出\r\nexport type { ProtocolParseResult } from './packages/tcp/protocolHandler.js';\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectManager.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/ConnectManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEhF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,YAAY,CAAC,uBAAuB,CAAC;IAC/E,wBAAwB;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoC;IAEhE,aAAa;IACb,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAE/D,6BAA6B;IAC7B,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAMnD;;;;;;OAMG;IACG,SAAS,CACd,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAyB,EAC/B,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACrC,OAAO,CAAC,aAAa,CAAC;IA4CzB;;;;OAIG;IACG,cAAc,CACnB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAyB,EAC/B,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC,IAAI,CAAC;IAqBhB;;OAEG;IACH,aAAa,IAAI,IAAI;IAQrB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IA+BhC;;;;;OAKG;YACW,uBAAuB;IA4BrC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK9B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectManager.js","sourceRoot":"","sources":["../../../src/packages/tcp/ConnectManager.ts"],"names":[],"mappings":"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","sourcesContent":["// ALL_CODE_LINE: 330\r\n// AI_CODE_LINE: 151\r\n\r\nimport { EventEmitter } from 'eventemitter3';\r\nimport type { ConnectionManagerEvents, SocketConnectOptions } from './types.js';\r\nimport { DEFAULT_TCP_PORT } from './constants.js';\r\nimport { SocketWrapper } from './SocketWrapper.js';\r\n\r\n/**\r\n * MINI连接管理器\r\n */\r\nexport class MiniConnectionManager extends EventEmitter<ConnectionManagerEvents> {\r\n\t/** 连接池 - 每个地址只维护一个连接 */\r\n\tprivate readonly connections = new Map<string, SocketWrapper>();\r\n\r\n\t/** 默认连接选项 */\r\n\tprivate readonly defaultOptions: Partial<SocketConnectOptions>;\r\n\r\n\t/** 标记是否正在销毁,避免销毁过程中触发自动重连 */\r\n\tprivate isShuttingDown = false;\r\n\r\n\tconstructor(options?: Partial<SocketConnectOptions>) {\r\n\t\tsuper();\r\n\r\n\t\tthis.defaultOptions = { ...options };\r\n\t}\r\n\r\n\t/**\r\n\t * 连接到指定设备\r\n\t * @param address 设备地址\r\n\t * @param port 设备端口\r\n\t * @param options 连接选项\r\n\t * @returns Promise<SocketWrapper> Socket包装器\r\n\t */\r\n\tasync connectTo(\r\n\t\taddress: string,\r\n\t\tport: number = DEFAULT_TCP_PORT,\r\n\t\toptions?: Partial<SocketConnectOptions>\r\n\t): Promise<SocketWrapper> {\r\n\t\tconst connectionId = this.getConnectionId(address, port);\r\n\r\n\t\t// 检查是否已存在连接(可能是自己之前的连接)\r\n\t\tif (this.connections.has(connectionId)) {\r\n\t\t\tconst existingSocketWrapper = this.connections.get(connectionId);\r\n\t\t\tif (existingSocketWrapper) {\r\n\t\t\t\treturn existingSocketWrapper;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// 在建立新连接前,主动断开其他设备的连接,实现后来的连接挤占前一个连接\r\n\t\tawait this.preemptOtherConnections(connectionId, address);\r\n\r\n\t\t// 创建Socket包装器\r\n\t\tconst mergedOptions = {\r\n\t\t\t...this.defaultOptions,\r\n\t\t\t...options,\r\n\t\t};\r\n\r\n\t\tif (this.isBuiltInDevice(address)) {\r\n\t\t\tmergedOptions.autoReconnect = true;\r\n\t\t\tmergedOptions.maxReconnectAttempts = 0;\r\n\t\t}\r\n\r\n\t\t// 合并选项,直接使用 SocketConnectOptions\r\n\t\tconst socketOptions: SocketConnectOptions = {\r\n\t\t\t...mergedOptions,\r\n\t\t};\r\n\r\n\t\tconst socketWrapper = new SocketWrapper();\r\n\r\n\t\t// 存储连接(在连接前存储,确保事件触发时可获取)\r\n\t\tthis.connections.set(connectionId, socketWrapper);\r\n\r\n\t\t// 设置事件监听\r\n\t\tthis.setupSocketEventHandlers(socketWrapper, connectionId);\r\n\r\n\t\tsocketWrapper.connect(address, port, socketOptions);\r\n\r\n\t\t// 返回 SocketWrapper 实例\r\n\t\treturn socketWrapper;\r\n\t}\r\n\r\n\t/**\r\n\t * 断开指定设备的连接\r\n\t * @param address 设备地址\r\n\t * @param port 设备端口\r\n\t */\r\n\tasync disconnectFrom(\r\n\t\taddress: string,\r\n\t\tport: number = DEFAULT_TCP_PORT,\r\n\t\toptions?: { autoReconnect?: boolean }\r\n\t): Promise<void> {\r\n\t\tconst _autoReconnect = options?.autoReconnect ?? false;\r\n\r\n\t\t// UI 场景下不允许删除内置设备连接,除非明确要求关闭自动重连\r\n\t\tif (!this.isShuttingDown && !_autoReconnect && this.isBuiltInDevice(address)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst connectionId = this.getConnectionId(address, port);\r\n\r\n\t\tconst socketWrapper = this.connections.get(connectionId);\r\n\r\n\t\tif (socketWrapper) {\r\n\t\t\tawait socketWrapper.disconnect();\r\n\t\t\tthis.connections.delete(connectionId);\r\n\r\n\t\t\t// 触发断开事件,传递 SocketWrapper\r\n\t\t\tthis.emit('disconnected', socketWrapper);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 断开所有连接\r\n\t */\r\n\tdisconnectAll(): void {\r\n\t\tfor (const [, socketWrapper] of this.connections) {\r\n\t\t\tsocketWrapper.disconnect();\r\n\t\t}\r\n\r\n\t\tthis.connections.clear();\r\n\t}\r\n\r\n\t/**\r\n\t * 生成连接ID\r\n\t * @param address 设备地址\r\n\t * @param port 设备端口\r\n\t * @returns string\r\n\t */\r\n\tprivate getConnectionId(address: string, port: number): string {\r\n\t\treturn `${address}:${port}`;\r\n\t}\r\n\r\n\t/**\r\n\t * 设置Socket事件处理器\r\n\t * @param socketWrapper Socket包装器\r\n\t * @param connectionId 连接ID\r\n\t */\r\n\tprivate setupSocketEventHandlers(socketWrapper: SocketWrapper, connectionId: string): void {\r\n\t\tconst tcpWrapper = socketWrapper.getTcpWrapper();\r\n\t\tsocketWrapper.on('connected', () => {\r\n\t\t\t// 触发连接事件(包括首次连接和自动重连),传递 SocketWrapper\r\n\t\t\tthis.emit('connected', socketWrapper);\r\n\t\t});\r\n\r\n\t\tsocketWrapper.on('disconnected', () => {\r\n\t\t\tthis.emit('disconnected', socketWrapper);\r\n\r\n\t\t\t// 内置设备:保留实例等待自动重连\r\n\t\t\t// 外置设备:删除实例(即使显式启用了自动重连,被动断连时也应该删除)\r\n\t\t\tconst address = tcpWrapper.getAddress();\r\n\t\t\tif (address && !this.isBuiltInDevice(address)) {\r\n\t\t\t\tthis.connections.delete(connectionId);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tsocketWrapper.on('error', (error: Error) => {\r\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\r\n\t\t\tthis.emit('error', errorMessage, socketWrapper);\r\n\r\n\t\t\t// 如果重连失败(达到最大次数)或非内置设备连接失败,清理实例\r\n\t\t\t// 对于首次连接失败,如果不是内置设备,也会清理\r\n\t\t\tconst address = tcpWrapper.getAddress();\r\n\t\t\tif (address && !this.isBuiltInDevice(address)) {\r\n\t\t\t\tthis.connections.delete(connectionId);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 在发起新连接前,断开现有的其他设备连接,确保同一时间仅保留一个MINI设备连接\r\n\t * 仅当目标设备与已连接设备的地址不同(不同MINI)时,才会执行挤占\r\n\t * @param activeConnectionId 新的连接ID\r\n\t * @param activeAddress 新设备的地址\r\n\t */\r\n\tprivate async preemptOtherConnections(activeConnectionId: string, activeAddress: string): Promise<void> {\r\n\t\tconst targets = Array.from(this.connections.entries()).filter(([connectionId, socketWrapper]) => {\r\n\t\t\tconst tcpWrapper = socketWrapper.getTcpWrapper();\r\n\t\t\tconst address = tcpWrapper.getAddress();\r\n\t\t\treturn connectionId !== activeConnectionId && address !== null && address !== activeAddress;\r\n\t\t});\r\n\r\n\t\tif (targets.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tawait Promise.all(\r\n\t\t\ttargets.map(async ([, socketWrapper]) => {\r\n\t\t\t\tconst tcpWrapper = socketWrapper.getTcpWrapper();\r\n\t\t\t\tconst address = tcpWrapper.getAddress();\r\n\t\t\t\tconst port = tcpWrapper.getPort();\r\n\t\t\t\tif (address && port) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tawait this.disconnectFrom(address, port, { autoReconnect: true });\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error';\r\n\t\t\t\t\t\tthis.emit('error', `主动断开旧连接失败(${address}:${port}): ${message}`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * 判断是否为内置设备(127.0.0.1)\r\n\t * @param address 设备地址\r\n\t * @returns boolean\r\n\t */\r\n\tprivate isBuiltInDevice(address: string): boolean {\r\n\t\treturn address === '127.0.0.1' || address === '::1' || address === 'localhost';\r\n\t}\r\n\r\n\t/**\r\n\t * 销毁连接管理器\r\n\t */\r\n\tasync destroy(): Promise<void> {\r\n\t\tthis.isShuttingDown = true;\r\n\t\tawait this.disconnectAll();\r\n\t\tthis.removeAllListeners();\r\n\t}\r\n}\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QueueManager.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/QueueManager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,YAAY,CAOxD,CAAC;AAEF;;;GAGG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,mBAAmB,CAA0B;gBAEzC,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC;IAUhD;;;;;;;OAOG;IACH,UAAU,CACT,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EACtF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,EACnD,iBAAiB,CAAC,EAAE,GAAG,GACrB,IAAI;IAuBP;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIvC;;OAEG;IACH,cAAc,CACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EACtF,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,EAClD,iBAAiB,CAAC,EAAE,GAAG,GACrB,IAAI;IAkBP;;OAEG;IACH,KAAK,IAAI,IAAI;CAIb"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QueueManager.js","sourceRoot":"","sources":["../../../src/packages/tcp/QueueManager.ts"],"names":[],"mappings":"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","sourcesContent":["// ALL_CODE_LINE: 120\r\n// AI_CODE_LINE: 2\r\nimport PQueue from 'p-queue';\r\nimport type { QueueOptions } from './types.js';\r\nimport { QueueOverflowStrategy } from './types.js';\r\n\r\n/**\r\n * 默认队列配置\r\n */\r\nexport const DEFAULT_QUEUE_OPTIONS: Required<QueueOptions> = {\r\n\t/** 最大队列长度,默认 1000 */\r\n\tmaxLength: 1000,\r\n\t/** 溢出策略*/\r\n\toverflowStrategy: QueueOverflowStrategy.DROP_OLDEST,\r\n\t/** 单条数据处理超时时间(毫秒),默认 5000 */\r\n\tprocessTimeout: 5000,\r\n};\r\n\r\n/**\r\n * 队列管理器\r\n * 负责处理数据队列、去重等功能\r\n */\r\nexport class QueueManager {\r\n\tprivate queue: PQueue;\r\n\tprivate queueOptions: Required<QueueOptions>;\r\n\tprivate processedRequestIds: Set<number> = new Set();\r\n\r\n\tconstructor(queueOptions: Required<QueueOptions>) {\r\n\t\tthis.queueOptions = queueOptions;\r\n\r\n\t\t// 初始化 p-queue\r\n\t\tthis.queue = new PQueue({\r\n\t\t\tconcurrency: 1, // 串行处理,保证顺序\r\n\t\t\ttimeout: this.queueOptions.processTimeout,\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 添加任务到队列\r\n\t * @param requestId 请求ID\r\n\t * @param data 数据\r\n\t * @param processor 处理函数\r\n\t * @param onError 错误处理函数\r\n\t * @param cachedParseResult 已解析的结果(可选,用于避免重复解析)\r\n\t */\r\n\taddToQueue(\r\n\t\trequestId: number,\r\n\t\tdata: Buffer,\r\n\t\tprocessor: (requestId: number, data: Buffer, cachedParseResult?: any) => Promise<void>,\r\n\t\tonError?: (error: Error, requestId: number) => void,\r\n\t\tcachedParseResult?: any\r\n\t): void {\r\n\t\tthis.queue\r\n\t\t\t.add(async () => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t// 处理队列项\r\n\t\t\t\t\tawait processor(requestId, data, cachedParseResult);\r\n\r\n\t\t\t\t\t// 去重标记\r\n\t\t\t\t\tthis.processedRequestIds.add(requestId);\r\n\t\t\t\t\t// 限制去重集合大小,防止内存泄漏\r\n\t\t\t\t\tif (this.processedRequestIds.size > this.queueOptions.maxLength * 2) {\r\n\t\t\t\t\t\tthis.processedRequestIds.clear();\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tthrow error; // 重新抛出,让 p-queue 处理\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t.catch((error) => {\r\n\t\t\t\t// p-queue 的超时错误会在这里捕获\r\n\t\t\t\tonError?.(error, requestId);\r\n\t\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 检查是否可以添加到队列\r\n\t */\r\n\tcanAdd(): boolean {\r\n\t\treturn this.queue.size < this.queueOptions.maxLength;\r\n\t}\r\n\r\n\t/**\r\n\t * 检查是否已处理过(去重)\r\n\t */\r\n\tisProcessed(requestId: number): boolean {\r\n\t\treturn this.processedRequestIds.has(requestId);\r\n\t}\r\n\r\n\t/**\r\n\t * 处理队列溢出\r\n\t */\r\n\thandleOverflow(\r\n\t\trequestId: number,\r\n\t\tdata: Buffer,\r\n\t\tprocessor: (requestId: number, data: Buffer, cachedParseResult?: any) => Promise<void>,\r\n\t\tonError: (error: Error, requestId: number) => void,\r\n\t\tcachedParseResult?: any\r\n\t): void {\r\n\t\tswitch (this.queueOptions.overflowStrategy) {\r\n\t\t\tcase QueueOverflowStrategy.DROP_NEWEST:\r\n\t\t\t\t// 丢弃最新数据\r\n\t\t\t\tbreak;\r\n\t\t\tcase QueueOverflowStrategy.REJECT:\r\n\t\t\t\t// 拒绝新数据并触发错误\r\n\t\t\t\tconst error = new Error(`Queue overflow: max length ${this.queueOptions.maxLength} reached`);\r\n\t\t\t\tonError(error, requestId);\r\n\t\t\t\tbreak;\r\n\t\t\tcase QueueOverflowStrategy.DROP_OLDEST:\r\n\t\t\tdefault:\r\n\t\t\t\t// p-queue 不支持直接丢弃最旧的任务\r\n\t\t\t\tthis.addToQueue(requestId, data, processor, onError, cachedParseResult);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 清空队列\r\n\t */\r\n\tclear(): void {\r\n\t\tthis.queue.clear();\r\n\t\tthis.processedRequestIds.clear();\r\n\t}\r\n}\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SocketWrapper.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/SocketWrapper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC1G,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAW7C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,cAAc;IACxE,YAAY;IACZ,OAAO,CAAC,UAAU,CAAa;IAE/B,YAAY;IACZ,OAAO,CAAC,YAAY,CAAe;IAEnC,YAAY;IACZ,OAAO,CAAC,eAAe,CAAkB;IAEzC,mCAAmC;IACnC,OAAO,CAAC,cAAc,CAAkC;IAExD,0BAA0B;IAC1B,OAAO,CAAC,aAAa,CAAuB;IAE5C;;;OAGG;gBACS,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAmChD;;;OAGG;IACH,OAAO,CAAC,eAAe;IAOvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAuC1B;;;OAGG;IACH,OAAO,CAAC,aAAa;IA6CrB;;;;;OAKG;YACW,gBAAgB;IAiB9B;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;;OAGG;IACH,OAAO,CAAC,aAAa;IAcrB;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAIxE;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM;IAkB1C;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI7B;;;OAGG;IACH,aAAa,IAAI,UAAU;CAG3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SocketWrapper.js","sourceRoot":"","sources":["../../../src/packages/tcp/SocketWrapper.ts"],"names":[],"mappings":"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","sourcesContent":["// ALL_CODE_LINE: 329\r\n// AI_CODE_LINE: 53\r\nimport { EventEmitter } from 'events';\r\nimport type { ISocketWrapper, SocketConnectOptions, QueueOptions, ProtocolSendPayload } from './types.js';\r\nimport { TcpWrapper } from './tcpWrapper.js';\r\nimport { QueueManager, DEFAULT_QUEUE_OPTIONS } from './QueueManager.js';\r\nimport { ProtocolHandler } from './protocolHandler.js';\r\n\r\n/**\r\n * 心跳数据常量(预定义 Buffer,避免重复转换)\r\n */\r\nconst HEARTBEAT_PING = Buffer.from('ping', 'utf8');\r\nconst HEARTBEAT_PONG = Buffer.from('pong', 'utf8');\r\nconst HEARTBEAT_LENGTH = 4;\r\n\r\n/**\r\n * SocketWrapper - TCP Socket 最小传输封装\r\n *\r\n * 职责:\r\n * - 仅负责 TCP 连接的字节级可靠传输\r\n * - 事件化接口:提供 connected/data/error/close 事件\r\n * - 协议支持:集成 Uniform Protocol 协议解析和构建\r\n * - 并发请求支持:通过 requestId 管理多个并发请求的发送和响应匹配\r\n * - 缓冲管理:维护接收缓冲区并按 requestId 管理\r\n * - 队列管理:支持队列长度限制、溢出策略、去重、监控等\r\n *\r\n * 事件:\r\n * - 'connected': 连接成功时触发\r\n * - 'disconnected': 连接彻底关闭时触发\r\n * - 'data': 接收到协议数据时触发 (data: any, requestId: number)\r\n * - 'error': 发生错误时触发 (error: Error, requestId?: number)\r\n */\r\nexport class SocketWrapper extends EventEmitter implements ISocketWrapper {\r\n\t/** 连接管理器 */\r\n\tprivate tcpWrapper: TcpWrapper;\r\n\r\n\t/** 队列管理器 */\r\n\tprivate queueManager: QueueManager;\r\n\r\n\t/** 协议处理器 */\r\n\tprivate protocolHandler: ProtocolHandler;\r\n\r\n\t/** 接收缓冲区,按 requestId 索引存储接收到的数据 */\r\n\tprivate receiveBuffers: Map<number, Buffer> = new Map();\r\n\r\n\t/** 接收数据缓冲区,用于处理不完整的数据包 */\r\n\tprivate receiveBuffer: Buffer | null = null;\r\n\r\n\t/**\r\n\t * 构造函数\r\n\t * @param queueOptions 队列配置选项\r\n\t */\r\n\tconstructor(queueOptions?: Partial<QueueOptions>) {\r\n\t\tsuper();\r\n\r\n\t\tthis.protocolHandler = new ProtocolHandler();\r\n\r\n\t\t// 初始化连接管理器和队列管理器\r\n\t\tthis.tcpWrapper = new TcpWrapper();\r\n\t\t// 合并默认配置和用户配置\r\n\t\tthis.queueManager = new QueueManager({\r\n\t\t\t...DEFAULT_QUEUE_OPTIONS,\r\n\t\t\t...queueOptions,\r\n\t\t});\r\n\r\n\t\t// 设置连接管理器的事件回调\r\n\t\tthis.tcpWrapper.setEventHandlers({\r\n\t\t\t/** 连接成功回调:TCP Socket 成功建立连接时触发,同时启动心跳机制并重置重连计数器 */\r\n\t\t\tonConnected: () => {\r\n\t\t\t\tthis.emit('connected');\r\n\t\t\t},\r\n\t\t\t/** 连接断开回调(自动重连场景):Socket 关闭且会重连,或心跳超时且启用自动重连时触发,表示临时断开 */\r\n\t\t\tonDisconnected: () => {},\r\n\t\t\t/** 接收数据回调:Socket 接收到非心跳数据时触发,心跳响应会被内部处理不传递给上层 */\r\n\t\t\tonData: (data: Buffer) => {\r\n\t\t\t\tthis.handleReceiveData(data);\r\n\t\t\t},\r\n\t\t\t/** 错误回调:连接参数无效、Socket 错误/超时、连接超时、重连异常等错误情况时触发 */\r\n\t\t\tonError: (error: Error) => {\r\n\t\t\t\tthis.emit('error', error);\r\n\t\t\t},\r\n\t\t\t/** 连接关闭回调:连接彻底关闭时触发(手动断开、达到最大重连次数、连接信息缺失),不会再有重连尝试 */\r\n\t\t\tonClose: () => {\r\n\t\t\t\tthis.emit('disconnected');\r\n\t\t\t},\r\n\t\t});\r\n\t}\r\n\t/**\r\n\t * 检查是否是心跳数据(ping/pong)\r\n\t * 使用 Buffer 直接比较,避免字符串转换开销\r\n\t */\r\n\tprivate isHeartbeatData(buffer: Buffer): boolean {\r\n\t\tif (buffer.length !== HEARTBEAT_LENGTH) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn buffer.equals(HEARTBEAT_PING) || buffer.equals(HEARTBEAT_PONG);\r\n\t}\r\n\r\n\t/**\r\n\t * 接收数据处理\r\n\t * @param data 接收到的数据\r\n\t */\r\n\tprivate handleReceiveData(data: Buffer): void {\r\n\t\t// 检查是否是心跳数据,如果是则直接跳过,不进入协议解析流程\r\n\t\tif (this.isHeartbeatData(data)) {\r\n\t\t\treturn; // 心跳数据由 tcpWrapper 处理,不进入协议解析\r\n\t\t}\r\n\r\n\t\t// 将新数据追加到接收缓冲区(优化:避免不必要的 Buffer.concat)\r\n\t\tif (!this.receiveBuffer || this.receiveBuffer.length === 0) {\r\n\t\t\tthis.receiveBuffer = data;\r\n\t\t} else {\r\n\t\t\tthis.receiveBuffer = Buffer.concat([this.receiveBuffer, data]);\r\n\t\t}\r\n\r\n\t\t// 处理协议数据\r\n\t\tthis.handleProtocolData();\r\n\t}\r\n\r\n\t/**\r\n\t * 处理协议数据(使用半包粘包处理)\r\n\t * 使用循环替代递归,避免栈溢出风险\r\n\t */\r\n\tprivate handleProtocolData(): void {\r\n\t\tif (!this.receiveBuffer) return;\r\n\r\n\t\t// 循环处理,直到没有更多数据需要处理\r\n\t\twhile (this.receiveBuffer) {\r\n\t\t\t// 检查并过滤心跳数据(处理粘包情况:心跳数据 + 协议数据)\r\n\t\t\tif (this.receiveBuffer.length >= HEARTBEAT_LENGTH) {\r\n\t\t\t\tconst first4Bytes = this.receiveBuffer.slice(0, HEARTBEAT_LENGTH);\r\n\t\t\t\tif (this.isHeartbeatData(first4Bytes)) {\r\n\t\t\t\t\t// 移除前 4 字节的心跳数据,继续处理剩余数据\r\n\t\t\t\t\tthis.receiveBuffer =\r\n\t\t\t\t\t\tthis.receiveBuffer.length > HEARTBEAT_LENGTH ? this.receiveBuffer.slice(HEARTBEAT_LENGTH) : null;\r\n\t\t\t\t\tcontinue; // 继续循环处理剩余数据\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 提取所有完整协议包(自动校验)\r\n\t\t\tconst { packets, remaining, invalidPackets } = this.protocolHandler.extractAllCompletePackets(this.receiveBuffer);\r\n\r\n\t\t\t// 处理校验失败的废包\r\n\t\t\tif (invalidPackets.length > 0) {\r\n\t\t\t\tthis.emit('error', new Error(`Invalid packets detected: ${invalidPackets.length} packets dropped`));\r\n\t\t\t}\r\n\r\n\t\t\t// 处理每个有效完整包\r\n\t\t\tfor (const packet of packets) {\r\n\t\t\t\tthis.processPacket(packet);\r\n\t\t\t}\r\n\r\n\t\t\t// 更新接收缓冲区为剩余数据(半包数据保留)\r\n\t\t\tthis.receiveBuffer = remaining;\r\n\r\n\t\t\t// 如果没有剩余数据,退出循环\r\n\t\t\tif (!remaining || remaining.length === 0) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 处理单个协议包\r\n\t * @param packet 协议包数据\r\n\t */\r\n\tprivate processPacket(packet: Buffer): void {\r\n\t\t// 先解析获取 requestId(用于去重和队列管理)\r\n\t\tlet requestId: number;\r\n\t\tlet parseResult: any;\r\n\t\ttry {\r\n\t\t\tparseResult = this.protocolHandler.parse(packet);\r\n\t\t\trequestId = parseResult.requestId;\r\n\t\t} catch (error) {\r\n\t\t\tthis.emit('error', error instanceof Error ? error : new Error(String(error)));\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 去重检查(响应包允许使用相同的 requestId,跳过去重检查)\r\n\t\tif (!parseResult.isResponse && this.queueManager.isProcessed(requestId)) {\r\n\t\t\tthis.emit('error', new Error(`Duplicate requestId detected, dropping: ${requestId}`), requestId);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 队列处理回调函数(提取为常量,避免重复创建)\r\n\t\tconst processor = (reqId: number, data: Buffer, cachedParseResult?: any) =>\r\n\t\t\tthis.processQueueItem(reqId, data, cachedParseResult);\r\n\t\tconst errorHandler = (error: Error, reqId: number) => this.emit('error', error, reqId);\r\n\r\n\t\t// 检查队列长度限制\r\n\t\tif (!this.queueManager.canAdd()) {\r\n\t\t\tthis.queueManager.handleOverflow(\r\n\t\t\t\trequestId,\r\n\t\t\t\tpacket,\r\n\t\t\t\tprocessor,\r\n\t\t\t\terrorHandler,\r\n\t\t\t\tparseResult // 传递已解析的结果\r\n\t\t\t);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 使用队列管理器处理(传递已解析的结果,避免重复解析)\r\n\t\tthis.queueManager.addToQueue(\r\n\t\t\trequestId,\r\n\t\t\tpacket,\r\n\t\t\tprocessor,\r\n\t\t\terrorHandler,\r\n\t\t\tparseResult // 传递已解析的结果\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * 处理单个队列项\r\n\t * @param requestId 请求ID\r\n\t * @param data 数据\r\n\t * @param cachedParseResult 已解析的结果(如果已解析过,避免重复解析)\r\n\t */\r\n\tprivate async processQueueItem(requestId: number, data: Buffer, cachedParseResult?: any): Promise<void> {\r\n\t\t// 缓存原始数据(按 requestId 索引)\r\n\t\tthis.receiveBuffers.set(requestId, data);\r\n\r\n\t\ttry {\r\n\t\t\t// 如果已有解析结果,直接使用;否则重新解析\r\n\t\t\tconst parseResult = cachedParseResult || this.protocolHandler.parse(data);\r\n\r\n\t\t\t// 触发协议数据事件(使用parseResult.data,因为ProtocolParseResult中数据字段是data)\r\n\t\t\tthis.emit('data', parseResult.data, requestId);\r\n\t\t} catch (error) {\r\n\t\t\t// 解析失败,触发错误事件\r\n\t\t\tconst errorObj = error instanceof Error ? error : new Error(String(error));\r\n\t\t\tthis.emit('error', errorObj, requestId);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 清理资源\r\n\t */\r\n\tprivate cleanup(): void {\r\n\t\tthis.receiveBuffers.clear();\r\n\t\tthis.receiveBuffer = null;\r\n\t\tthis.queueManager.clear();\r\n\t}\r\n\r\n\t/**\r\n\t * 写入 socket\r\n\t * @param bytes 要写入的数据\r\n\t */\r\n\tprivate writeToSocket(bytes: Buffer): void {\r\n\t\tconst socket = this.tcpWrapper.getSocket();\r\n\t\tif (!socket?.writable) {\r\n\t\t\tthis.emit('error', new Error('Socket is not writable'));\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tsocket.write(bytes, (err?: Error | null) => {\r\n\t\t\tif (err) {\r\n\t\t\t\tthis.emit('error', err);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 连接建立\r\n\t * @param host 服务器主机地址\r\n\t * @param port 服务器端口号\r\n\t * @param options 连接选项\r\n\t */\r\n\tconnect(host: string, port: number, options: SocketConnectOptions): void {\r\n\t\tthis.tcpWrapper.connect(host, port, options);\r\n\t}\r\n\r\n\t/**\r\n\t * 发送协议数据包\r\n\t * @param payload 协议负载对象\r\n\t * @returns 实际使用的 requestId(seqId,由系统自动生成)\r\n\t */\r\n\tsend(payload: ProtocolSendPayload): number {\r\n\t\tconst buildOptions: any = {\r\n\t\t\tisResponse: false, // 默认请求包\r\n\t\t\t...payload,\r\n\t\t};\r\n\r\n\t\t// 如果业务侧需要指定 seqId(如响应包需要匹配请求),可以通过 options.seqId 传入\r\n\t\tif (typeof buildOptions.seqId !== 'number') {\r\n\t\t\tbuildOptions.seqId = this.protocolHandler.generateSeqId();\r\n\t\t}\r\n\r\n\t\tconst buffer = this.protocolHandler.build(payload);\r\n\t\tconst resolvedRequestId = buildOptions.seqId;\r\n\r\n\t\tthis.writeToSocket(buffer);\r\n\t\treturn resolvedRequestId;\r\n\t}\r\n\r\n\t/**\r\n\t * 断开连接\r\n\t */\r\n\tdisconnect(): void {\r\n\t\t// 先清理本地资源\r\n\t\tthis.cleanup();\r\n\t\t// 再断开连接(会停止心跳和重连)\r\n\t\tthis.tcpWrapper.disconnect();\r\n\t}\r\n\r\n\t/**\r\n\t * 检查是否已连接\r\n\t */\r\n\tisConnected(): boolean {\r\n\t\treturn this.tcpWrapper.isConnected();\r\n\t}\r\n\r\n\t/**\r\n\t * 主动触发 error 事件\r\n\t * 用于外部主动报告错误,例如业务逻辑错误、数据验证错误等\r\n\t * @param error 错误对象\r\n\t */\r\n\temitError(error: Error): void {\r\n\t\tthis.emit('error', error);\r\n\t}\r\n\r\n\t/**\r\n\t * 获取内部的 TcpWrapper 实例\r\n\t * @returns TcpWrapper 实例\r\n\t */\r\n\tgetTcpWrapper(): TcpWrapper {\r\n\t\treturn this.tcpWrapper;\r\n\t}\r\n}\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/constants.ts"],"names":[],"mappings":"AAGA,cAAc;AACd,eAAO,MAAM,gBAAgB;;CAEnB,CAAC;AAEX,cAAc;AACd,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAEtC,aAAa;AACb,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,eAAe;AACf,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAE5C,iBAAiB;AACjB,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C,iBAAiB;AACjB,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C,mBAAmB;AACnB,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,mBAAmB;AACnB,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AAEpD,iBAAiB;AACjB,eAAO,MAAM,kCAAkC,OAAO,CAAC;AAEvD,qBAAqB;AACrB,eAAO,MAAM,2BAA2B,QAAQ,CAAC;AAEjD,eAAe;AACf,eAAO,MAAM,8BAA8B,IAAI,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/packages/tcp/constants.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,mBAAmB;AAEnB,cAAc;AACd,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC/B,IAAI,EAAE,0BAA0B;CACvB,CAAC;AAEX,cAAc;AACd,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAEtC,aAAa;AACb,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,eAAe;AACf,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAE5C,iBAAiB;AACjB,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAE/C,iBAAiB;AACjB,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAE/C,mBAAmB;AACnB,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAE9C,mBAAmB;AACnB,MAAM,CAAC,MAAM,8BAA8B,GAAG,KAAK,CAAC;AAEpD,iBAAiB;AACjB,MAAM,CAAC,MAAM,kCAAkC,GAAG,IAAI,CAAC;AAEvD,qBAAqB;AACrB,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC,CAAC,MAAM;AAExD,eAAe;AACf,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC","sourcesContent":["// ALL_CODE_LINE: 50\r\n// AI_CODE_LINE: 20\r\n\r\n/** 支持的设备型号 */\r\nexport const SUPPORTED_MODELS = {\r\n\tMINI: 'U5 MINI Event Controller',\r\n} as const;\r\n\r\n/** 默认TCP端口 */\r\nexport const DEFAULT_TCP_PORT = 17100;\r\n\r\n/** 默认启用心跳 */\r\nexport const DEFAULT_ENABLE_HEARTBEAT = true;\r\n\r\n/** 默认自动重连开关 */\r\nexport const DEFAULT_AUTO_RECONNECT = false;\r\n\r\n/** 默认心跳间隔(毫秒) */\r\nexport const DEFAULT_HEARTBEAT_INTERVAL = 5000;\r\n\r\n/** 默认重连间隔(毫秒) */\r\nexport const DEFAULT_RECONNECT_INTERVAL = 5000;\r\n\r\n/** 默认心跳超时时间(毫秒) */\r\nexport const DEFAULT_HEARTBEAT_TIMEOUT = 5000;\r\n\r\n/** 默认最大重连间隔(毫秒) */\r\nexport const DEFAULT_MAX_RECONNECT_INTERVAL = 60000;\r\n\r\n/** 默认是否启用指数退避 */\r\nexport const DEFAULT_ENABLE_EXPONENTIAL_BACKOFF = true;\r\n\r\n/** 默认mDNS查询间隔(毫秒) */\r\nexport const DEFAULT_MDNS_QUERY_INTERVAL = 10000; // 10秒\r\n\r\n/** 默认最大重连次数 */\r\nexport const DEFAULT_MAX_RECONNECT_ATTEMPTS = 0;\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/demo.ts"],"names":[],"mappings":"AAOA,iBAAe,IAAI,kBAyKlB;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
// ALL_CODE_LINE: 161
|
|
2
|
-
// AI_CODE_LINE: 161
|
|
3
|
-
import { SocketWrapper } from './SocketWrapper.js';
|
|
4
|
-
import { QueueOverflowStrategy } from './types.js';
|
|
5
|
-
async function demo() {
|
|
6
|
-
console.log('🚀 Starting SocketWrapper Demo...\n');
|
|
7
|
-
const socketWrapper = new SocketWrapper({
|
|
8
|
-
maxLength: 1000,
|
|
9
|
-
overflowStrategy: QueueOverflowStrategy.DROP_NEWEST,
|
|
10
|
-
processTimeout: 5000,
|
|
11
|
-
});
|
|
12
|
-
socketWrapper.on('connected', () => {
|
|
13
|
-
console.log('✅ Socket connected');
|
|
14
|
-
console.log(' - Connection established successfully');
|
|
15
|
-
console.log(' - Heartbeat mechanism started');
|
|
16
|
-
console.log(' - Reconnect counter reset\n');
|
|
17
|
-
});
|
|
18
|
-
socketWrapper.on('disconnected', () => {
|
|
19
|
-
console.log('⚠️ Socket disconnected, will retry...');
|
|
20
|
-
console.log(' - Connection lost but will attempt to reconnect');
|
|
21
|
-
console.log(' - Auto-reconnect is enabled\n');
|
|
22
|
-
});
|
|
23
|
-
socketWrapper.on('data', (data, requestId) => {
|
|
24
|
-
console.log(`📨 Received data from server (RequestId: ${requestId}):`);
|
|
25
|
-
console.log(` Data:`, JSON.stringify(data, null, 2));
|
|
26
|
-
console.log('');
|
|
27
|
-
});
|
|
28
|
-
socketWrapper.on('error', (error, requestId) => {
|
|
29
|
-
console.error(`❌ Socket error: ${error.message}`);
|
|
30
|
-
if (requestId !== undefined) {
|
|
31
|
-
console.error(` - RequestId: ${requestId}`);
|
|
32
|
-
}
|
|
33
|
-
console.error(` - Error stack: ${error.stack || 'N/A'}\n`);
|
|
34
|
-
});
|
|
35
|
-
socketWrapper.on('close', () => {
|
|
36
|
-
console.log('🔌 Socket closed');
|
|
37
|
-
console.log(' - Connection permanently closed');
|
|
38
|
-
console.log(' - No more reconnection attempts will be made\n');
|
|
39
|
-
});
|
|
40
|
-
// 连接配置
|
|
41
|
-
// 默认使用本地测试服务器(先运行 npm run test-server 或 npx tsx src/packages/tcp/test-server.ts)
|
|
42
|
-
const connectOptions = {
|
|
43
|
-
host: process.env.TEST_HOST || '127.0.0.1', // 默认本地测试服务器
|
|
44
|
-
port: parseInt(process.env.TEST_PORT || '8080', 10), // 默认端口 8080
|
|
45
|
-
// 自动重连配置
|
|
46
|
-
autoReconnect: true, // 启用自动重连
|
|
47
|
-
reconnectInterval: 5000, // 重连间隔 5 秒
|
|
48
|
-
maxReconnectAttempts: 10, // 最大重连次数
|
|
49
|
-
// 重连限制配置
|
|
50
|
-
enableExponentialBackoff: true, // 启用指数退避(重连间隔逐渐增加:5s -> 10s -> 20s -> 40s -> 60s...)
|
|
51
|
-
maxReconnectInterval: 60000, // 最大重连间隔 60 秒
|
|
52
|
-
// 心跳配置(默认使用内置 ping/pong)
|
|
53
|
-
enableHeartbeat: true, // 启用心跳
|
|
54
|
-
heartbeatInterval: 5000, // 心跳间隔 5 秒
|
|
55
|
-
heartbeatTimeout: 5000, // 心跳超时 5 秒(无响应则关闭连接)
|
|
56
|
-
};
|
|
57
|
-
console.log('🔌 Connecting to server...');
|
|
58
|
-
console.log(` Host: ${connectOptions.host}`);
|
|
59
|
-
console.log(` Port: ${connectOptions.port}\n`);
|
|
60
|
-
// 连接到设备
|
|
61
|
-
socketWrapper.connect(connectOptions.host || '127.0.0.1', connectOptions.port || 8080, connectOptions);
|
|
62
|
-
// 等待连接建立
|
|
63
|
-
await new Promise((resolve) => {
|
|
64
|
-
socketWrapper.once('connected', resolve);
|
|
65
|
-
setTimeout(resolve, 10000); // 最多等待 10 秒
|
|
66
|
-
});
|
|
67
|
-
if (!socketWrapper.isConnected()) {
|
|
68
|
-
console.error('❌ Failed to connect\n');
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
// ============================================
|
|
72
|
-
// 示例:发送测试数据
|
|
73
|
-
// ============================================
|
|
74
|
-
console.log('📤 Sending test data...');
|
|
75
|
-
const testPayload = {
|
|
76
|
-
data: { row: 1, col: 3, type: 0 },
|
|
77
|
-
header: { seq: 0, sn: '', source: '' },
|
|
78
|
-
options: {},
|
|
79
|
-
};
|
|
80
|
-
const requestId = socketWrapper.send(testPayload);
|
|
81
|
-
console.log(` - RequestId: ${requestId}`);
|
|
82
|
-
console.log(` - Payload:`, testPayload);
|
|
83
|
-
console.log('');
|
|
84
|
-
// 等待接收响应
|
|
85
|
-
console.log('⏳ Waiting for response...\n');
|
|
86
|
-
// 保持连接一段时间以观察自动重连(如果断开)
|
|
87
|
-
console.log('⏳ Keeping connection alive...');
|
|
88
|
-
if (connectOptions.enableExponentialBackoff) {
|
|
89
|
-
console.log(` - Base interval: ${connectOptions.reconnectInterval}ms`);
|
|
90
|
-
console.log(` - Max interval: ${connectOptions.maxReconnectInterval}ms`);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
console.log(` - Fixed interval: ${connectOptions.reconnectInterval}ms\n`);
|
|
94
|
-
}
|
|
95
|
-
console.log(' 💓 Heartbeat Configuration:');
|
|
96
|
-
if (connectOptions.enableHeartbeat) {
|
|
97
|
-
console.log(` - Interval: ${connectOptions.heartbeatInterval}ms`);
|
|
98
|
-
console.log(` - Timeout: ${connectOptions.heartbeatTimeout}ms`);
|
|
99
|
-
console.log(` - Behavior: send 'ping' every ${connectOptions.heartbeatInterval}ms and expect 'pong' within ${connectOptions.heartbeatTimeout}ms\n`);
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
console.log(` - Enabled: No\n`);
|
|
103
|
-
}
|
|
104
|
-
// 等待用户中断或保持运行
|
|
105
|
-
await new Promise((resolve) => {
|
|
106
|
-
let isExiting = false;
|
|
107
|
-
let reconnectCheckTimeout = null;
|
|
108
|
-
// 处理 Ctrl+C 优雅退出
|
|
109
|
-
const exitHandler = () => {
|
|
110
|
-
if (isExiting)
|
|
111
|
-
return;
|
|
112
|
-
isExiting = true;
|
|
113
|
-
if (reconnectCheckTimeout) {
|
|
114
|
-
clearTimeout(reconnectCheckTimeout);
|
|
115
|
-
}
|
|
116
|
-
console.log('\n\n🛑 Shutting down...');
|
|
117
|
-
socketWrapper.disconnect();
|
|
118
|
-
console.log(' Disconnected\n');
|
|
119
|
-
resolve();
|
|
120
|
-
};
|
|
121
|
-
process.on('SIGINT', exitHandler);
|
|
122
|
-
process.on('SIGTERM', exitHandler);
|
|
123
|
-
// 监听重连事件,如果重连成功就不显示失败消息
|
|
124
|
-
let reconnectAttempted = false;
|
|
125
|
-
socketWrapper.on('disconnected', () => {
|
|
126
|
-
reconnectAttempted = true;
|
|
127
|
-
// 如果启用了自动重连,等待重连,不立即显示失败
|
|
128
|
-
});
|
|
129
|
-
socketWrapper.on('connected', () => {
|
|
130
|
-
// 重连成功,清除之前的失败检查
|
|
131
|
-
if (reconnectAttempted) {
|
|
132
|
-
reconnectAttempted = false;
|
|
133
|
-
if (reconnectCheckTimeout) {
|
|
134
|
-
clearTimeout(reconnectCheckTimeout);
|
|
135
|
-
reconnectCheckTimeout = null;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
// 延迟检查连接状态,给自动重连一些时间
|
|
140
|
-
reconnectCheckTimeout = setTimeout(() => {
|
|
141
|
-
if (!socketWrapper.isConnected() && !reconnectAttempted) {
|
|
142
|
-
// 只有在没有重连尝试的情况下才显示失败
|
|
143
|
-
console.log('⚠️ Connection failed. Will exit in 10 seconds...');
|
|
144
|
-
console.log(' (Press Ctrl+C to exit immediately)\n');
|
|
145
|
-
setTimeout(() => {
|
|
146
|
-
if (!socketWrapper.isConnected() && !isExiting) {
|
|
147
|
-
console.log('⏰ Auto-exiting due to connection failure...\n');
|
|
148
|
-
exitHandler();
|
|
149
|
-
}
|
|
150
|
-
}, 10000);
|
|
151
|
-
}
|
|
152
|
-
}, 2000); // 等待2秒,给自动重连时间
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
export { demo };
|
|
156
|
-
// 直接执行 demo(当文件被直接运行时)
|
|
157
|
-
// 使用方式: npm run demo 或 npx tsx src/packages/tcp/demo.ts
|
|
158
|
-
if (import.meta.url === `file://${process.argv[1]?.replace(/\\/g, '/')}` || process.argv[1]?.includes('demo.ts')) {
|
|
159
|
-
demo().catch((error) => {
|
|
160
|
-
console.error('Demo error:', error);
|
|
161
|
-
process.exit(1);
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
//# sourceMappingURL=demo.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../../../src/packages/tcp/demo.ts"],"names":[],"mappings":"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","sourcesContent":["// ALL_CODE_LINE: 161\r\n// AI_CODE_LINE: 161\r\n\r\nimport { SocketWrapper } from './SocketWrapper.js';\r\nimport type { SocketConnectOptions } from './types.js';\r\nimport { QueueOverflowStrategy } from './types.js';\r\n\r\nasync function demo() {\r\n\tconsole.log('🚀 Starting SocketWrapper Demo...\\n');\r\n\r\n\tconst socketWrapper = new SocketWrapper({\r\n\t\tmaxLength: 1000,\r\n\t\toverflowStrategy: QueueOverflowStrategy.DROP_NEWEST,\r\n\t\tprocessTimeout: 5000,\r\n\t});\r\n\r\n\tsocketWrapper.on('connected', () => {\r\n\t\tconsole.log('✅ Socket connected');\r\n\t\tconsole.log(' - Connection established successfully');\r\n\t\tconsole.log(' - Heartbeat mechanism started');\r\n\t\tconsole.log(' - Reconnect counter reset\\n');\r\n\t});\r\n\r\n\tsocketWrapper.on('disconnected', () => {\r\n\t\tconsole.log('⚠️ Socket disconnected, will retry...');\r\n\t\tconsole.log(' - Connection lost but will attempt to reconnect');\r\n\t\tconsole.log(' - Auto-reconnect is enabled\\n');\r\n\t});\r\n\r\n\tsocketWrapper.on('data', (data: any, requestId: number) => {\r\n\t\tconsole.log(`📨 Received data from server (RequestId: ${requestId}):`);\r\n\t\tconsole.log(` Data:`, JSON.stringify(data, null, 2));\r\n\t\tconsole.log('');\r\n\t});\r\n\r\n\tsocketWrapper.on('error', (error: Error, requestId?: number) => {\r\n\t\tconsole.error(`❌ Socket error: ${error.message}`);\r\n\t\tif (requestId !== undefined) {\r\n\t\t\tconsole.error(` - RequestId: ${requestId}`);\r\n\t\t}\r\n\t\tconsole.error(` - Error stack: ${error.stack || 'N/A'}\\n`);\r\n\t});\r\n\r\n\tsocketWrapper.on('close', () => {\r\n\t\tconsole.log('🔌 Socket closed');\r\n\t\tconsole.log(' - Connection permanently closed');\r\n\t\tconsole.log(' - No more reconnection attempts will be made\\n');\r\n\t});\r\n\r\n\t// 连接配置\r\n\t// 默认使用本地测试服务器(先运行 npm run test-server 或 npx tsx src/packages/tcp/test-server.ts)\r\n\tconst connectOptions: SocketConnectOptions = {\r\n\t\thost: process.env.TEST_HOST || '127.0.0.1', // 默认本地测试服务器\r\n\t\tport: parseInt(process.env.TEST_PORT || '8080', 10), // 默认端口 8080\r\n\t\t// 自动重连配置\r\n\t\tautoReconnect: true, // 启用自动重连\r\n\t\treconnectInterval: 5000, // 重连间隔 5 秒\r\n\t\tmaxReconnectAttempts: 10, // 最大重连次数\r\n\t\t// 重连限制配置\r\n\t\tenableExponentialBackoff: true, // 启用指数退避(重连间隔逐渐增加:5s -> 10s -> 20s -> 40s -> 60s...)\r\n\t\tmaxReconnectInterval: 60000, // 最大重连间隔 60 秒\r\n\t\t// 心跳配置(默认使用内置 ping/pong)\r\n\t\tenableHeartbeat: true, // 启用心跳\r\n\t\theartbeatInterval: 5000, // 心跳间隔 5 秒\r\n\t\theartbeatTimeout: 5000, // 心跳超时 5 秒(无响应则关闭连接)\r\n\t};\r\n\r\n\tconsole.log('🔌 Connecting to server...');\r\n\tconsole.log(` Host: ${connectOptions.host}`);\r\n\tconsole.log(` Port: ${connectOptions.port}\\n`);\r\n\r\n\t// 连接到设备\r\n\tsocketWrapper.connect(connectOptions.host || '127.0.0.1', connectOptions.port || 8080, connectOptions);\r\n\r\n\t// 等待连接建立\r\n\tawait new Promise((resolve) => {\r\n\t\tsocketWrapper.once('connected', resolve);\r\n\t\tsetTimeout(resolve, 10000); // 最多等待 10 秒\r\n\t});\r\n\r\n\tif (!socketWrapper.isConnected()) {\r\n\t\tconsole.error('❌ Failed to connect\\n');\r\n\t\treturn;\r\n\t}\r\n\r\n\t// ============================================\r\n\t// 示例:发送测试数据\r\n\t// ============================================\r\n\tconsole.log('📤 Sending test data...');\r\n\tconst testPayload = {\r\n\t\tdata: { row: 1, col: 3, type: 0 },\r\n\t\theader: { seq: 0, sn: '', source: '' },\r\n\t\toptions: {},\r\n\t};\r\n\tconst requestId = socketWrapper.send(testPayload);\r\n\tconsole.log(` - RequestId: ${requestId}`);\r\n\tconsole.log(` - Payload:`, testPayload);\r\n\tconsole.log('');\r\n\r\n\t// 等待接收响应\r\n\tconsole.log('⏳ Waiting for response...\\n');\r\n\r\n\t// 保持连接一段时间以观察自动重连(如果断开)\r\n\tconsole.log('⏳ Keeping connection alive...');\r\n\tif (connectOptions.enableExponentialBackoff) {\r\n\t\tconsole.log(` - Base interval: ${connectOptions.reconnectInterval}ms`);\r\n\t\tconsole.log(` - Max interval: ${connectOptions.maxReconnectInterval}ms`);\r\n\t} else {\r\n\t\tconsole.log(` - Fixed interval: ${connectOptions.reconnectInterval}ms\\n`);\r\n\t}\r\n\r\n\tconsole.log(' 💓 Heartbeat Configuration:');\r\n\tif (connectOptions.enableHeartbeat) {\r\n\t\tconsole.log(` - Interval: ${connectOptions.heartbeatInterval}ms`);\r\n\t\tconsole.log(` - Timeout: ${connectOptions.heartbeatTimeout}ms`);\r\n\t\tconsole.log(\r\n\t\t\t` - Behavior: send 'ping' every ${connectOptions.heartbeatInterval}ms and expect 'pong' within ${connectOptions.heartbeatTimeout}ms\\n`\r\n\t\t);\r\n\t} else {\r\n\t\tconsole.log(` - Enabled: No\\n`);\r\n\t}\r\n\r\n\t// 等待用户中断或保持运行\r\n\tawait new Promise<void>((resolve) => {\r\n\t\tlet isExiting = false;\r\n\t\tlet reconnectCheckTimeout: NodeJS.Timeout | null = null;\r\n\r\n\t\t// 处理 Ctrl+C 优雅退出\r\n\t\tconst exitHandler = () => {\r\n\t\t\tif (isExiting) return;\r\n\t\t\tisExiting = true;\r\n\t\t\tif (reconnectCheckTimeout) {\r\n\t\t\t\tclearTimeout(reconnectCheckTimeout);\r\n\t\t\t}\r\n\t\t\tconsole.log('\\n\\n🛑 Shutting down...');\r\n\t\t\tsocketWrapper.disconnect();\r\n\t\t\tconsole.log(' Disconnected\\n');\r\n\t\t\tresolve();\r\n\t\t};\r\n\r\n\t\tprocess.on('SIGINT', exitHandler);\r\n\t\tprocess.on('SIGTERM', exitHandler);\r\n\r\n\t\t// 监听重连事件,如果重连成功就不显示失败消息\r\n\t\tlet reconnectAttempted = false;\r\n\t\tsocketWrapper.on('disconnected', () => {\r\n\t\t\treconnectAttempted = true;\r\n\t\t\t// 如果启用了自动重连,等待重连,不立即显示失败\r\n\t\t});\r\n\r\n\t\tsocketWrapper.on('connected', () => {\r\n\t\t\t// 重连成功,清除之前的失败检查\r\n\t\t\tif (reconnectAttempted) {\r\n\t\t\t\treconnectAttempted = false;\r\n\t\t\t\tif (reconnectCheckTimeout) {\r\n\t\t\t\t\tclearTimeout(reconnectCheckTimeout);\r\n\t\t\t\t\treconnectCheckTimeout = null;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// 延迟检查连接状态,给自动重连一些时间\r\n\t\treconnectCheckTimeout = setTimeout(() => {\r\n\t\t\tif (!socketWrapper.isConnected() && !reconnectAttempted) {\r\n\t\t\t\t// 只有在没有重连尝试的情况下才显示失败\r\n\t\t\t\tconsole.log('⚠️ Connection failed. Will exit in 10 seconds...');\r\n\t\t\t\tconsole.log(' (Press Ctrl+C to exit immediately)\\n');\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\tif (!socketWrapper.isConnected() && !isExiting) {\r\n\t\t\t\t\t\tconsole.log('⏰ Auto-exiting due to connection failure...\\n');\r\n\t\t\t\t\t\texitHandler();\r\n\t\t\t\t\t}\r\n\t\t\t\t}, 10000);\r\n\t\t\t}\r\n\t\t}, 2000); // 等待2秒,给自动重连时间\r\n\t});\r\n}\r\n\r\nexport { demo };\r\n\r\n// 直接执行 demo(当文件被直接运行时)\r\n// 使用方式: npm run demo 或 npx tsx src/packages/tcp/demo.ts\r\nif (import.meta.url === `file://${process.argv[1]?.replace(/\\\\/g, '/')}` || process.argv[1]?.includes('demo.ts')) {\r\n\tdemo().catch((error) => {\r\n\t\tconsole.error('Demo error:', error);\r\n\t\tprocess.exit(1);\r\n\t});\r\n}\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discoveryService.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/discoveryService.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGjG;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,YAAY,CAAC,eAAe,CAAC;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2C;IAC7E,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAAwB;gBAE3B,OAAO,CAAC,EAAE,uBAAuB;IAW7C;;OAEG;IACH,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,cAAc;IA2BtB;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAInB;;;OAGG;IACH,IAAI,YAAY,IAAI,oBAAoB,EAAE,CAEzC;IAED;;OAEG;IACH,OAAO,IAAI,IAAI;CAqCf"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discoveryService.js","sourceRoot":"","sources":["../../../src/packages/tcp/discoveryService.ts"],"names":[],"mappings":"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","sourcesContent":["// ALL_CODE_LINE: 197\r\n// AI_CODE_LINE: 38\r\n\r\nimport { EventEmitter } from 'eventemitter3';\r\nimport type { Browser, DiscoveredService as BonjourService } from '@julusian/bonjour-service';\r\nimport { Bonjour } from '@julusian/bonjour-service';\r\nimport type { DiscoveryEvents, DiscoveryServiceOptions, MiniDiscoveredDevice } from './types.js';\r\nimport { DEFAULT_MDNS_QUERY_INTERVAL, SUPPORTED_MODELS } from './constants.js';\r\n\r\n/**\r\n * MINI设备发现服务\r\n * 使用Bonjour/mDNS进行设备自动发现\r\n */\r\nexport class MiniDiscoveryService extends EventEmitter<DiscoveryEvents> {\r\n\tprivate readonly options: Required<DiscoveryServiceOptions>;\r\n\tprivate readonly discoveredDevices = new Map<string, MiniDiscoveredDevice>();\r\n\tprivate queryInterval: NodeJS.Timeout | null = null;\r\n\tprivate isDestroyed = false;\r\n\tprivate bonjour: Bonjour | null = null;\r\n\tprivate browser: Browser | null = null;\r\n\r\n\tconstructor(options?: DiscoveryServiceOptions) {\r\n\t\tsuper();\r\n\r\n\t\tthis.options = {\r\n\t\t\tqueryInterval: options?.queryInterval ?? DEFAULT_MDNS_QUERY_INTERVAL, // 10秒\r\n\t\t\ttype: options?.type ?? 'pixelhue',\r\n\t\t\tprotocol: options?.protocol ?? 'tcp',\r\n\t\t};\r\n\r\n\t\tthis.startDiscovery();\r\n\t}\r\n\t/**\r\n\t * 开始设备发现\r\n\t */\r\n\tprivate startDiscovery(): void {\r\n\t\tif (this.isDestroyed) return;\r\n\r\n\t\t// 初始化 mDNS 浏览器\r\n\t\tthis.bonjour = new Bonjour();\r\n\t\tconst type = this.options.type || 'pixelhue';\r\n\t\tconst protocol = (this.options.protocol || 'tcp') as 'tcp' | 'udp';\r\n\t\tthis.browser = this.bonjour.find({ type, protocol });\r\n\r\n\t\tif (this.browser) {\r\n\t\t\tthis.browser.on('up', (service: BonjourService) => this.emitUp(service));\r\n\t\t\tthis.browser.on('down', (service: BonjourService) => this.emitDown(service));\r\n\t\t\tthis.browser.on('srv-update', (newService: BonjourService, existingService: BonjourService) => {\r\n\t\t\t\tthis.emitDown(existingService);\r\n\t\t\t\tthis.emitUp(newService);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// 立即触发一次查询\r\n\t\tthis.query();\r\n\r\n\t\t// 设置定期查询\r\n\t\tif (this.options.queryInterval > 0) {\r\n\t\t\tthis.queryInterval = setInterval(() => {\r\n\t\t\t\tthis.query();\r\n\t\t\t}, this.options.queryInterval);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate emitUp(service: BonjourService): void {\r\n\t\tconst device = this.convertService(service);\r\n\t\tif (!device) return;\r\n\r\n\t\tconst deviceId = this.getDeviceId(device.address, device.port);\r\n\t\tconst existingDevice = this.discoveredDevices.get(deviceId);\r\n\t\tif (!existingDevice) {\r\n\t\t\tthis.discoveredDevices.set(deviceId, device);\r\n\t\t} else {\r\n\t\t\texistingDevice.lastSeen = new Date();\r\n\t\t}\r\n\t\tthis.emit('up', device);\r\n\t}\r\n\r\n\tprivate emitDown(service: BonjourService): void {\r\n\t\tconst device = this.convertService(service);\r\n\t\tif (!device) return;\r\n\r\n\t\tconst deviceId = this.getDeviceId(device.address, device.port);\r\n\t\tconst existingDevice = this.discoveredDevices.get(deviceId);\r\n\t\tif (existingDevice) {\r\n\t\t\tthis.discoveredDevices.delete(deviceId);\r\n\t\t\tthis.emit('down', existingDevice);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate convertService(service: BonjourService): MiniDiscoveredDevice | null {\r\n\t\t// 如果没有地址,返回 null\r\n\t\tif (!service.host) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// 从 txt 记录提取元数据(字段名需与MINI固件一致,如无则使用默认)\r\n\t\tconst txt: Record<string, string> = service.txt || {};\r\n\t\tconst serialNumber: string = txt.sn || 'UNKNOWN';\r\n\t\tconst _version: string = txt.version || '1.0.0';\r\n\t\tconst model: string = txt.model || SUPPORTED_MODELS.MINI;\r\n\t\tconst displayName: string = txt.displayName || 'Pixelhue U5 MINI';\r\n\t\tconst keyRows = Number(txt.rows) || 4;\r\n\t\tconst keyCols = Number(txt.cols) || 10;\r\n\r\n\t\treturn {\r\n\t\t\taddress: service.host,\r\n\t\t\tport: service.port, // 设备端口\r\n\t\t\tname: displayName, // 设备名称\r\n\t\t\tserialNumber, // 设备序列号,唯一标识设备\r\n\t\t\tversion: _version, // 固件版本号\r\n\t\t\tmodelName: model, // 设备型号名称\r\n\t\t\tkeyLayout: { rows: keyRows, columns: keyCols }, // 按键布局(行数和列数)\r\n\t\t\tlastSeen: new Date(),\r\n\t\t};\r\n\t}\r\n\r\n\t/**\r\n\t * 手动查询设备(马上刷新服务列表,同时清理过期的服务)\r\n\t */\r\n\tquery(): void {\r\n\t\tif (this.isDestroyed) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 告诉浏览器发送查询,并过期旧服务\r\n\t\tthis.browser?.update();\r\n\t\tthis.browser?.expire();\r\n\t}\r\n\r\n\t/**\r\n\t * 获取设备ID\r\n\t * @param address 设备地址\r\n\t * @param port 设备端口\r\n\t */\r\n\tprivate getDeviceId(address: string, port: number): string {\r\n\t\treturn `${address}:${port}`;\r\n\t}\r\n\r\n\t/**\r\n\t * 获取所有已发现的设备\r\n\t * @returns 已发现的设备数组\r\n\t */\r\n\tget knownDevices(): MiniDiscoveredDevice[] {\r\n\t\treturn Array.from(this.discoveredDevices.values());\r\n\t}\r\n\r\n\t/**\r\n\t * 销毁发现服务\r\n\t */\r\n\tdestroy(): void {\r\n\t\tthis.isDestroyed = true;\r\n\r\n\t\t// 清理定时器\r\n\t\tif (this.queryInterval) {\r\n\t\t\tclearInterval(this.queryInterval);\r\n\t\t\tthis.queryInterval = null;\r\n\t\t}\r\n\r\n\t\t// 清空所有发现的设备并触发下线事件\r\n\t\tfor (const device of this.discoveredDevices.values()) {\r\n\t\t\tthis.emit('down', device);\r\n\t\t}\r\n\t\tthis.discoveredDevices.clear();\r\n\r\n\t\t// 停止浏览器\r\n\t\tif (this.browser) {\r\n\t\t\ttry {\r\n\t\t\t\tthis.browser.stop();\r\n\t\t\t} catch (error) {\r\n\t\t\t\t// 忽略停止浏览器时的错误,避免影响销毁流程\r\n\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\r\n\t\t\t\tconsole.warn('停止浏览器时发生错误:', errorMessage);\r\n\t\t\t}\r\n\t\t\tthis.browser.removeAllListeners(); // 避免继续响应网络事件,比如up、down、srv-update等\r\n\t\t\tthis.browser = null;\r\n\t\t}\r\n\r\n\t\t// 销毁 Bonjour 实例\r\n\t\tif (this.bonjour) {\r\n\t\t\tthis.bonjour.destroy();\r\n\t\t\tthis.bonjour = null;\r\n\t\t}\r\n\r\n\t\t// 移除所有事件监听器\r\n\t\tthis.removeAllListeners(); // 清理当前DiscoveryService(继承自EventEmitter)的所有事件监听器,避免内存泄漏\r\n\t}\r\n}\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"protocolHandler.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/protocolHandler.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,WAAW;IACX,IAAI,EAAE,GAAG,CAAC;IACV,WAAW;IACX,MAAM,EAAE,GAAG,CAAC;IACZ,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,UAAU,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,OAAO,CAAM;IAErB;;;OAGG;;IAMH;;;;OAIG;IACI,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB;IAuBjD;;;;;;OAMG;IACI,KAAK,CACX,IAAI,EAAE,GAAG,EACT,MAAM;;;;KAIL,EACD,OAAO,KAAK,GACV,MAAM;IAKT;;;OAGG;IACI,aAAa,IAAI,MAAM;IAI9B;;OAEG;IACI,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI;IAYjG;;OAEG;IACI,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG;QACjD,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,cAAc,EAAE,MAAM,EAAE,CAAC;KACzB;CAUD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"protocolHandler.js","sourceRoot":"","sources":["../../../src/packages/tcp/protocolHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// ALL_CODE_LINE: 142\n// AI_CODE_LINE: 1\n\n/**\n * Uniform Protocol 协议处理模块\n * 封装协议解析、校验和构建功能\n */\n\nimport { UniformProtocolParser } from '@unico/uniform-protocol-parser';\nimport { UniformProtocolBuilder } from '@unico/uniform-protocol-builder';\n\n/**\n * 协议处理结果\n */\nexport interface ProtocolParseResult {\n\t/** 解析结果 */\n\tdata: any;\n\t/** 头部数据 */\n\theader: any;\n\t/** 请求ID(seqId) */\n\trequestId: number;\n\t/** 是否为响应包 */\n\tisResponse: boolean;\n}\n\n/**\n * Uniform Protocol 协议处理器\n */\nexport class ProtocolHandler {\n\tprivate parser: any;\n\tprivate builder: any;\n\n\t/**\n\t * 构造函数\n\t * @param options 协议处理选项\n\t */\n\tconstructor() {\n\t\tthis.parser = new UniformProtocolParser({ enableChecksum: false });\n\t\tthis.builder = new UniformProtocolBuilder();\n\t}\n\n\t/**\n\t * 解析协议数据包\n\t * @param buffer 原始数据缓冲区\n\t * @returns 解析结果和请求ID\n\t */\n\tpublic parse(buffer: Buffer): ProtocolParseResult {\n\t\ttry {\n\t\t\t// parser.parse 内部需要 ArrayBuffer,需要转换\n\t\t\tconst arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n\t\t\tconst result = this.parser.parse(arrayBuffer);\n\n\t\t\treturn {\n\t\t\t\tdata:\n\t\t\t\t\tresult.tlv2.jsonData !== undefined\n\t\t\t\t\t\t? result.tlv2.jsonData\n\t\t\t\t\t\t: JSON.parse(new TextDecoder().decode(new Uint8Array(result.tlv2.data))),\n\t\t\t\theader:\n\t\t\t\t\tresult.tlv1.jsonData !== undefined\n\t\t\t\t\t\t? result.tlv1.jsonData\n\t\t\t\t\t\t: JSON.parse(new TextDecoder().decode(new Uint8Array(result.tlv1.data))),\n\t\t\t\trequestId: result.requestHead.seqId,\n\t\t\t\tisResponse: result.requestHead.isResponse,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * 构建协议数据包\n\t * @param data 业务数据(TLV2 的数据部分,通常是 JSON 对象)\n\t * @param header TLV1 的头部数据(通常是 JSON 对象)\n\t * @param options 构建选项(会与默认选项合并)\n\t * @returns 构建好的数据包 Buffer\n\t */\n\tpublic build(\n\t\tdata: any,\n\t\theader = {\n\t\t\tseq: 0,\n\t\t\tsn: '',\n\t\t\tsource: '',\n\t\t},\n\t\toptions = {}\n\t): Buffer {\n\t\tconst result = this.builder.build(data, header, options);\n\t\treturn Buffer.from(result);\n\t}\n\n\t/**\n\t * 生成 seqId\n\t * @returns 序列ID(3字节)\n\t */\n\tpublic generateSeqId(): number {\n\t\treturn this.builder.generateSeqId();\n\t}\n\n\t/**\n\t * 从缓冲区中提取完整协议包(处理半包/粘包)\n\t */\n\tpublic extractCompletePacket(buffer: Buffer): { packet: Buffer; remaining: Buffer | null } | null {\n\t\tconst result = this.parser.extractCompletePacket(buffer);\n\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tpacket: result.packet,\n\t\t\tremaining: result.remaining || null,\n\t\t};\n\t}\n\n\t/**\n\t * 从缓冲区中提取所有完整协议包(处理粘包)\n\t */\n\tpublic extractAllCompletePackets(buffer: Buffer): {\n\t\tpackets: Buffer[];\n\t\tremaining: Buffer | null;\n\t\tinvalidPackets: Buffer[];\n\t} {\n\t\tconst result = this.parser.extractAllCompletePackets(buffer);\n\n\t\t// parser 已优化,直接返回 Buffer 数组\n\t\treturn {\n\t\t\tpackets: result.packets,\n\t\t\tremaining: result.remaining || null,\n\t\t\tinvalidPackets: result.invalidPackets,\n\t\t};\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tcpWrapper.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/tcpWrapper.ts"],"names":[],"mappings":"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"}
|