@panguard-ai/manager 0.2.0 → 0.2.1
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/LICENSE +1 -1
- package/dist/agent-registry.d.ts.map +1 -1
- package/dist/agent-registry.js +1 -0
- package/dist/agent-registry.js.map +1 -1
- package/dist/dashboard-relay.d.ts +80 -0
- package/dist/dashboard-relay.d.ts.map +1 -0
- package/dist/dashboard-relay.js +465 -0
- package/dist/dashboard-relay.js.map +1 -0
- package/dist/db.d.ts +78 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +339 -0
- package/dist/db.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/manager.d.ts +40 -6
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +123 -10
- package/dist/manager.js.map +1 -1
- package/dist/server.d.ts +76 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +468 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +14 -2
package/LICENSE
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,SAAS,EAAE,MAAM;IAK7B;;;;;;;OAOG;IACH,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB;
|
|
1
|
+
{"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,SAAS,EAAE,MAAM;IAK7B;;;;;;;OAOG;IACH,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB;IAoCnE;;;;;OAKG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAezC;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,iBAAiB,GAAG,SAAS;IAkBzE;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAMxD;;;;OAIG;IACH,eAAe,IAAI,SAAS,iBAAiB,EAAE;IAM/C;;;;OAIG;IACH,YAAY,IAAI,SAAS,iBAAiB,EAAE;IAO5C;;;;;;OAMG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,iBAAiB,EAAE;IA8B/D;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAkBrC;;;;OAIG;IACH,eAAe,IAAI,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;IAc9C;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
package/dist/agent-registry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Relay Server - Proxies dashboard connections between agents and clients
|
|
3
|
+
* Dashboard Relay Server - 在 agent 和客戶端之間代理 dashboard 連接
|
|
4
|
+
*
|
|
5
|
+
* URL routing:
|
|
6
|
+
* /api/dashboard/relay/{agentId} - Agent upstream connections (Guard -> Manager)
|
|
7
|
+
* /api/dashboard/view/{agentId} - Client downstream connections (Browser -> Manager)
|
|
8
|
+
*
|
|
9
|
+
* When an agent sends an event, it is broadcast to all subscribed clients.
|
|
10
|
+
* When a client sends a command, it is forwarded to the target agent.
|
|
11
|
+
*
|
|
12
|
+
* Uses Node.js built-in http module with native RFC 6455 WebSocket handshake.
|
|
13
|
+
*
|
|
14
|
+
* @module @panguard-ai/manager/dashboard-relay
|
|
15
|
+
*/
|
|
16
|
+
import { EventEmitter } from 'node:events';
|
|
17
|
+
import type { IncomingMessage } from 'node:http';
|
|
18
|
+
import type { Socket } from 'node:net';
|
|
19
|
+
export interface DashboardRelayConfig {
|
|
20
|
+
/** Require auth for relay connections / 要求 relay 連接認證 */
|
|
21
|
+
readonly requireAuth?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Dashboard relay server -- proxies dashboard connections between agents and clients
|
|
25
|
+
* Dashboard relay server -- 在 agent 和客戶端之間代理 dashboard 連接
|
|
26
|
+
*/
|
|
27
|
+
export declare class DashboardRelay extends EventEmitter {
|
|
28
|
+
/** Map of agentId -> upstream agent WebSocket connection / agentId -> 上游 agent WebSocket 連接 */
|
|
29
|
+
private readonly agentConnections;
|
|
30
|
+
/** Map of agentId -> Set of downstream client connections / agentId -> 下游客戶端連接集合 */
|
|
31
|
+
private readonly clientConnections;
|
|
32
|
+
/** Configuration / 配置 */
|
|
33
|
+
private readonly config;
|
|
34
|
+
constructor(config?: DashboardRelayConfig);
|
|
35
|
+
/**
|
|
36
|
+
* Handle WebSocket upgrade for relay endpoint / 處理 relay 端點的 WebSocket 升級
|
|
37
|
+
*
|
|
38
|
+
* Routes based on URL path:
|
|
39
|
+
* /api/dashboard/relay/{agentId} -> agent connection
|
|
40
|
+
* /api/dashboard/view/{agentId} -> client connection
|
|
41
|
+
*/
|
|
42
|
+
handleUpgrade(req: IncomingMessage, socket: Socket, _head: Buffer): void;
|
|
43
|
+
/**
|
|
44
|
+
* Get connected agent IDs / 取得已連接的 agent ID 列表
|
|
45
|
+
*/
|
|
46
|
+
getConnectedAgents(): string[];
|
|
47
|
+
/**
|
|
48
|
+
* Get client count for an agent / 取得 agent 的客戶端數量
|
|
49
|
+
*/
|
|
50
|
+
getClientCount(agentId: string): number;
|
|
51
|
+
/**
|
|
52
|
+
* Disconnect all connections / 斷開所有連接
|
|
53
|
+
*/
|
|
54
|
+
disconnectAll(): void;
|
|
55
|
+
/** Handle agent WebSocket upgrade / 處理 agent WebSocket 升級 */
|
|
56
|
+
private handleAgentUpgrade;
|
|
57
|
+
/** Handle data from agent connection / 處理 agent 連接的資料 */
|
|
58
|
+
private handleAgentData;
|
|
59
|
+
/** Handle agent disconnect / 處理 agent 斷線 */
|
|
60
|
+
private handleAgentDisconnect;
|
|
61
|
+
/** Handle client WebSocket upgrade / 處理客戶端 WebSocket 升級 */
|
|
62
|
+
private handleClientUpgrade;
|
|
63
|
+
/** Handle data from client connection / 處理客戶端連接的資料 */
|
|
64
|
+
private handleClientData;
|
|
65
|
+
/** Handle client disconnect / 處理客戶端斷線 */
|
|
66
|
+
private handleClientDisconnect;
|
|
67
|
+
/** Broadcast a payload from agent to all subscribed clients / 將 agent 載荷廣播給所有訂閱的客戶端 */
|
|
68
|
+
private broadcastToClients;
|
|
69
|
+
/** Forward a payload from client to the target agent / 將客戶端載荷轉發給目標 agent */
|
|
70
|
+
private forwardToAgent;
|
|
71
|
+
/** Complete the WebSocket handshake / 完成 WebSocket 交握 */
|
|
72
|
+
private completeHandshake;
|
|
73
|
+
/** Create a WebSocket text frame (unmasked, server->client) / 建立 WebSocket 文字框架 */
|
|
74
|
+
private createWSFrame;
|
|
75
|
+
/** Extract payload from a WebSocket frame (handles both masked and unmasked) / 提取 WebSocket 框架載荷 */
|
|
76
|
+
private extractPayload;
|
|
77
|
+
/** Send a pong frame / 發送 pong 框架 */
|
|
78
|
+
private sendPong;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=dashboard-relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-relay.d.ts","sourceRoot":"","sources":["../src/dashboard-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWvC,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AASD;;;GAGG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,+FAA+F;IAC/F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6C;IAC9E,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkD;IACpF,yBAAyB;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,MAAM,CAAC,EAAE,oBAAoB;IAUzC;;;;;;OAMG;IACH,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAuBxE;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKvC;;OAEG;IACH,aAAa,IAAI,IAAI;IA8BrB,6DAA6D;IAC7D,OAAO,CAAC,kBAAkB;IAqE1B,yDAAyD;IACzD,OAAO,CAAC,eAAe;IA+BvB,4CAA4C;IAC5C,OAAO,CAAC,qBAAqB;IA4C7B,2DAA2D;IAC3D,OAAO,CAAC,mBAAmB;IAiE3B,sDAAsD;IACtD,OAAO,CAAC,gBAAgB;IAsBxB,yCAAyC;IACzC,OAAO,CAAC,sBAAsB;IA2B9B,uFAAuF;IACvF,OAAO,CAAC,kBAAkB;IAgC1B,4EAA4E;IAC5E,OAAO,CAAC,cAAc;IAkBtB,yDAAyD;IACzD,OAAO,CAAC,iBAAiB;IAwBzB,mFAAmF;IACnF,OAAO,CAAC,aAAa;IAuBrB,oGAAoG;IACpG,OAAO,CAAC,cAAc;IAiCtB,qCAAqC;IACrC,OAAO,CAAC,QAAQ;CAWjB"}
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Relay Server - Proxies dashboard connections between agents and clients
|
|
3
|
+
* Dashboard Relay Server - 在 agent 和客戶端之間代理 dashboard 連接
|
|
4
|
+
*
|
|
5
|
+
* URL routing:
|
|
6
|
+
* /api/dashboard/relay/{agentId} - Agent upstream connections (Guard -> Manager)
|
|
7
|
+
* /api/dashboard/view/{agentId} - Client downstream connections (Browser -> Manager)
|
|
8
|
+
*
|
|
9
|
+
* When an agent sends an event, it is broadcast to all subscribed clients.
|
|
10
|
+
* When a client sends a command, it is forwarded to the target agent.
|
|
11
|
+
*
|
|
12
|
+
* Uses Node.js built-in http module with native RFC 6455 WebSocket handshake.
|
|
13
|
+
*
|
|
14
|
+
* @module @panguard-ai/manager/dashboard-relay
|
|
15
|
+
*/
|
|
16
|
+
import { EventEmitter } from 'node:events';
|
|
17
|
+
import { createHash } from 'node:crypto';
|
|
18
|
+
import { createLogger } from '@panguard-ai/core';
|
|
19
|
+
const logger = createLogger('panguard-manager:dashboard-relay');
|
|
20
|
+
/** WebSocket magic GUID per RFC 6455 / RFC 6455 WebSocket 魔術 GUID */
|
|
21
|
+
const WS_MAGIC_GUID = '258EAFA5-E914-47DA-95CA-5AB5DC11E65B';
|
|
22
|
+
/** Maximum clients per agent / 每個 agent 的最大客戶端數 */
|
|
23
|
+
const MAX_CLIENTS_PER_AGENT = 50;
|
|
24
|
+
/**
|
|
25
|
+
* Dashboard relay server -- proxies dashboard connections between agents and clients
|
|
26
|
+
* Dashboard relay server -- 在 agent 和客戶端之間代理 dashboard 連接
|
|
27
|
+
*/
|
|
28
|
+
export class DashboardRelay extends EventEmitter {
|
|
29
|
+
/** Map of agentId -> upstream agent WebSocket connection / agentId -> 上游 agent WebSocket 連接 */
|
|
30
|
+
agentConnections = new Map();
|
|
31
|
+
/** Map of agentId -> Set of downstream client connections / agentId -> 下游客戶端連接集合 */
|
|
32
|
+
clientConnections = new Map();
|
|
33
|
+
/** Configuration / 配置 */
|
|
34
|
+
config;
|
|
35
|
+
constructor(config) {
|
|
36
|
+
super();
|
|
37
|
+
this.config = config ?? {};
|
|
38
|
+
logger.info(`Dashboard relay initialized (requireAuth: ${this.config.requireAuth ?? false}) / ` +
|
|
39
|
+
`Dashboard relay 已初始化`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handle WebSocket upgrade for relay endpoint / 處理 relay 端點的 WebSocket 升級
|
|
43
|
+
*
|
|
44
|
+
* Routes based on URL path:
|
|
45
|
+
* /api/dashboard/relay/{agentId} -> agent connection
|
|
46
|
+
* /api/dashboard/view/{agentId} -> client connection
|
|
47
|
+
*/
|
|
48
|
+
handleUpgrade(req, socket, _head) {
|
|
49
|
+
const url = req.url ?? '';
|
|
50
|
+
const agentRelayMatch = url.match(/^\/api\/dashboard\/relay\/([^/?]+)/);
|
|
51
|
+
const clientViewMatch = url.match(/^\/api\/dashboard\/view\/([^/?]+)/);
|
|
52
|
+
if (agentRelayMatch) {
|
|
53
|
+
const agentId = agentRelayMatch[1];
|
|
54
|
+
this.handleAgentUpgrade(req, socket, agentId);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (clientViewMatch) {
|
|
58
|
+
const agentId = clientViewMatch[1];
|
|
59
|
+
this.handleClientUpgrade(req, socket, agentId);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Unknown path -> reject / 未知路徑 -> 拒絕
|
|
63
|
+
logger.warn(`Rejected relay upgrade for unknown path: ${url} / 拒絕未知路徑的 relay 升級`);
|
|
64
|
+
socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
|
|
65
|
+
socket.destroy();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get connected agent IDs / 取得已連接的 agent ID 列表
|
|
69
|
+
*/
|
|
70
|
+
getConnectedAgents() {
|
|
71
|
+
return Array.from(this.agentConnections.keys());
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get client count for an agent / 取得 agent 的客戶端數量
|
|
75
|
+
*/
|
|
76
|
+
getClientCount(agentId) {
|
|
77
|
+
const clients = this.clientConnections.get(agentId);
|
|
78
|
+
return clients ? clients.size : 0;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Disconnect all connections / 斷開所有連接
|
|
82
|
+
*/
|
|
83
|
+
disconnectAll() {
|
|
84
|
+
// Close all agent connections / 關閉所有 agent 連接
|
|
85
|
+
for (const [agentId, conn] of this.agentConnections) {
|
|
86
|
+
try {
|
|
87
|
+
conn.socket.destroy();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
/* ignore */
|
|
91
|
+
}
|
|
92
|
+
this.agentConnections.delete(agentId);
|
|
93
|
+
}
|
|
94
|
+
// Close all client connections / 關閉所有客戶端連接
|
|
95
|
+
for (const [agentId, clients] of this.clientConnections) {
|
|
96
|
+
for (const client of clients) {
|
|
97
|
+
try {
|
|
98
|
+
client.socket.destroy();
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
/* ignore */
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
this.clientConnections.delete(agentId);
|
|
105
|
+
}
|
|
106
|
+
logger.info('All relay connections disconnected / 所有 relay 連接已斷開');
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Agent connection handling / Agent 連接處理
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
/** Handle agent WebSocket upgrade / 處理 agent WebSocket 升級 */
|
|
112
|
+
handleAgentUpgrade(req, socket, agentId) {
|
|
113
|
+
// Validate auth if required / 若需要則驗證認證
|
|
114
|
+
if (this.config.requireAuth) {
|
|
115
|
+
const authHeader = req.headers.authorization ?? '';
|
|
116
|
+
const token = authHeader.replace('Bearer ', '');
|
|
117
|
+
if (!token) {
|
|
118
|
+
logger.warn(`Agent relay auth failed for ${agentId} / Agent relay 認證失敗`);
|
|
119
|
+
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
|
|
120
|
+
socket.destroy();
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Complete WebSocket handshake / 完成 WebSocket 交握
|
|
125
|
+
if (!this.completeHandshake(req, socket))
|
|
126
|
+
return;
|
|
127
|
+
// If agent already connected, close old connection / 若 agent 已連接,關閉舊連接
|
|
128
|
+
const existing = this.agentConnections.get(agentId);
|
|
129
|
+
if (existing) {
|
|
130
|
+
logger.info(`Replacing existing agent connection for ${agentId} / 替換現有 agent 連接`);
|
|
131
|
+
try {
|
|
132
|
+
existing.socket.destroy();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
/* ignore */
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const conn = {
|
|
139
|
+
socket,
|
|
140
|
+
agentId,
|
|
141
|
+
connectedAt: Date.now(),
|
|
142
|
+
};
|
|
143
|
+
this.agentConnections.set(agentId, conn);
|
|
144
|
+
this.emit('agent:connected', agentId);
|
|
145
|
+
logger.info(`Agent ${agentId} connected to dashboard relay / ` +
|
|
146
|
+
`Agent ${agentId} 已連接到 dashboard relay`);
|
|
147
|
+
// Handle incoming data from agent (events to forward to clients)
|
|
148
|
+
// 處理從 agent 收到的資料(轉發給客戶端的事件)
|
|
149
|
+
socket.on('data', (data) => {
|
|
150
|
+
this.handleAgentData(agentId, socket, data);
|
|
151
|
+
});
|
|
152
|
+
socket.on('end', () => {
|
|
153
|
+
this.handleAgentDisconnect(agentId, socket);
|
|
154
|
+
});
|
|
155
|
+
socket.on('close', () => {
|
|
156
|
+
this.handleAgentDisconnect(agentId, socket);
|
|
157
|
+
});
|
|
158
|
+
socket.on('error', (err) => {
|
|
159
|
+
logger.warn(`Agent ${agentId} relay socket error: ${err.message} / Agent relay 連線錯誤`);
|
|
160
|
+
this.handleAgentDisconnect(agentId, socket);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/** Handle data from agent connection / 處理 agent 連接的資料 */
|
|
164
|
+
handleAgentData(agentId, socket, data) {
|
|
165
|
+
if (data.length < 2)
|
|
166
|
+
return;
|
|
167
|
+
const firstByte = data[0] ?? 0;
|
|
168
|
+
const opcode = firstByte & 0x0f;
|
|
169
|
+
// Close frame / 關閉框架
|
|
170
|
+
if (opcode === 0x08) {
|
|
171
|
+
this.handleAgentDisconnect(agentId, socket);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// Ping -> pong / Ping -> pong
|
|
175
|
+
if (opcode === 0x09) {
|
|
176
|
+
this.sendPong(this.agentConnections.get(agentId)?.socket);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// Pong -> ignore
|
|
180
|
+
if (opcode === 0x0a)
|
|
181
|
+
return;
|
|
182
|
+
// Text frame -> extract payload and broadcast to clients
|
|
183
|
+
// 文字框架 -> 提取載荷並廣播給客戶端
|
|
184
|
+
if (opcode === 0x01) {
|
|
185
|
+
const payload = this.extractPayload(data);
|
|
186
|
+
if (payload) {
|
|
187
|
+
this.broadcastToClients(agentId, payload);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** Handle agent disconnect / 處理 agent 斷線 */
|
|
192
|
+
handleAgentDisconnect(agentId, socket) {
|
|
193
|
+
const conn = this.agentConnections.get(agentId);
|
|
194
|
+
// Only remove if this is the current connection (not a replaced one)
|
|
195
|
+
// 只在這是當前連接時移除(而不是已被替換的連接)
|
|
196
|
+
if (!conn || conn.socket !== socket)
|
|
197
|
+
return;
|
|
198
|
+
try {
|
|
199
|
+
conn.socket.destroy();
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
/* ignore */
|
|
203
|
+
}
|
|
204
|
+
this.agentConnections.delete(agentId);
|
|
205
|
+
this.emit('agent:disconnected', agentId);
|
|
206
|
+
logger.info(`Agent ${agentId} disconnected from relay / ` +
|
|
207
|
+
`Agent ${agentId} 已從 relay 斷線`);
|
|
208
|
+
// Notify all connected clients that the agent is gone
|
|
209
|
+
// 通知所有已連接的客戶端 agent 已離線
|
|
210
|
+
const disconnectMsg = JSON.stringify({
|
|
211
|
+
type: 'agent_disconnected',
|
|
212
|
+
agentId,
|
|
213
|
+
timestamp: new Date().toISOString(),
|
|
214
|
+
});
|
|
215
|
+
const frame = this.createWSFrame(Buffer.from(disconnectMsg, 'utf-8'));
|
|
216
|
+
const clients = this.clientConnections.get(agentId);
|
|
217
|
+
if (clients) {
|
|
218
|
+
for (const client of clients) {
|
|
219
|
+
try {
|
|
220
|
+
client.socket.write(frame);
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
/* ignore */
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
// Client connection handling / 客戶端連接處理
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
/** Handle client WebSocket upgrade / 處理客戶端 WebSocket 升級 */
|
|
232
|
+
handleClientUpgrade(req, socket, agentId) {
|
|
233
|
+
// Check if agent exists / 檢查 agent 是否存在
|
|
234
|
+
if (!this.agentConnections.has(agentId)) {
|
|
235
|
+
logger.warn(`Client tried to view non-connected agent ${agentId} / ` +
|
|
236
|
+
`客戶端嘗試查看未連接的 agent`);
|
|
237
|
+
socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
|
|
238
|
+
socket.destroy();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
// Enforce max clients per agent / 限制每個 agent 的最大客戶端數
|
|
242
|
+
const existingClients = this.clientConnections.get(agentId);
|
|
243
|
+
if (existingClients && existingClients.size >= MAX_CLIENTS_PER_AGENT) {
|
|
244
|
+
logger.warn(`Max clients reached for agent ${agentId} / 客戶端數已達上限`);
|
|
245
|
+
socket.write('HTTP/1.1 503 Service Unavailable\r\n\r\n');
|
|
246
|
+
socket.destroy();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// Complete WebSocket handshake / 完成 WebSocket 交握
|
|
250
|
+
if (!this.completeHandshake(req, socket))
|
|
251
|
+
return;
|
|
252
|
+
const conn = {
|
|
253
|
+
socket,
|
|
254
|
+
agentId,
|
|
255
|
+
connectedAt: Date.now(),
|
|
256
|
+
};
|
|
257
|
+
if (!this.clientConnections.has(agentId)) {
|
|
258
|
+
this.clientConnections.set(agentId, new Set());
|
|
259
|
+
}
|
|
260
|
+
this.clientConnections.get(agentId).add(conn);
|
|
261
|
+
this.emit('client:connected', agentId);
|
|
262
|
+
logger.info(`Client connected to view agent ${agentId} (total: ${this.getClientCount(agentId)}) / ` +
|
|
263
|
+
`客戶端已連接查看 agent`);
|
|
264
|
+
// Handle incoming data from client (commands to forward to agent)
|
|
265
|
+
// 處理從客戶端收到的資料(轉發給 agent 的指令)
|
|
266
|
+
socket.on('data', (data) => {
|
|
267
|
+
this.handleClientData(agentId, data);
|
|
268
|
+
});
|
|
269
|
+
socket.on('end', () => {
|
|
270
|
+
this.handleClientDisconnect(agentId, conn);
|
|
271
|
+
});
|
|
272
|
+
socket.on('close', () => {
|
|
273
|
+
this.handleClientDisconnect(agentId, conn);
|
|
274
|
+
});
|
|
275
|
+
socket.on('error', () => {
|
|
276
|
+
this.handleClientDisconnect(agentId, conn);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/** Handle data from client connection / 處理客戶端連接的資料 */
|
|
280
|
+
handleClientData(agentId, data) {
|
|
281
|
+
if (data.length < 2)
|
|
282
|
+
return;
|
|
283
|
+
const firstByte = data[0] ?? 0;
|
|
284
|
+
const opcode = firstByte & 0x0f;
|
|
285
|
+
// Close frame
|
|
286
|
+
if (opcode === 0x08)
|
|
287
|
+
return;
|
|
288
|
+
// Ping -> pong
|
|
289
|
+
if (opcode === 0x09)
|
|
290
|
+
return;
|
|
291
|
+
// Pong -> ignore
|
|
292
|
+
if (opcode === 0x0a)
|
|
293
|
+
return;
|
|
294
|
+
// Text frame -> forward to agent / 文字框架 -> 轉發給 agent
|
|
295
|
+
if (opcode === 0x01) {
|
|
296
|
+
const payload = this.extractPayload(data);
|
|
297
|
+
if (payload) {
|
|
298
|
+
this.forwardToAgent(agentId, payload);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/** Handle client disconnect / 處理客戶端斷線 */
|
|
303
|
+
handleClientDisconnect(agentId, conn) {
|
|
304
|
+
try {
|
|
305
|
+
conn.socket.destroy();
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
/* ignore */
|
|
309
|
+
}
|
|
310
|
+
const clients = this.clientConnections.get(agentId);
|
|
311
|
+
if (clients) {
|
|
312
|
+
clients.delete(conn);
|
|
313
|
+
if (clients.size === 0) {
|
|
314
|
+
this.clientConnections.delete(agentId);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
this.emit('client:disconnected', agentId);
|
|
318
|
+
logger.info(`Client disconnected from agent ${agentId} (remaining: ${this.getClientCount(agentId)}) / ` +
|
|
319
|
+
`客戶端已從 agent 斷線`);
|
|
320
|
+
}
|
|
321
|
+
// ---------------------------------------------------------------------------
|
|
322
|
+
// Message forwarding / 訊息轉發
|
|
323
|
+
// ---------------------------------------------------------------------------
|
|
324
|
+
/** Broadcast a payload from agent to all subscribed clients / 將 agent 載荷廣播給所有訂閱的客戶端 */
|
|
325
|
+
broadcastToClients(agentId, payload) {
|
|
326
|
+
const clients = this.clientConnections.get(agentId);
|
|
327
|
+
if (!clients || clients.size === 0)
|
|
328
|
+
return;
|
|
329
|
+
// Re-frame the payload as an unmasked server->client frame
|
|
330
|
+
// 將載荷重新包裝為未遮罩的 server->client 框架
|
|
331
|
+
const frame = this.createWSFrame(payload);
|
|
332
|
+
const deadClients = [];
|
|
333
|
+
for (const client of clients) {
|
|
334
|
+
try {
|
|
335
|
+
client.socket.write(frame);
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
deadClients.push(client);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Cleanup dead clients / 清理斷線客戶端
|
|
342
|
+
for (const dead of deadClients) {
|
|
343
|
+
clients.delete(dead);
|
|
344
|
+
try {
|
|
345
|
+
dead.socket.destroy();
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
/* ignore */
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (clients.size === 0) {
|
|
352
|
+
this.clientConnections.delete(agentId);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/** Forward a payload from client to the target agent / 將客戶端載荷轉發給目標 agent */
|
|
356
|
+
forwardToAgent(agentId, payload) {
|
|
357
|
+
const agentConn = this.agentConnections.get(agentId);
|
|
358
|
+
if (!agentConn)
|
|
359
|
+
return;
|
|
360
|
+
try {
|
|
361
|
+
// Re-frame as unmasked server->client frame
|
|
362
|
+
const frame = this.createWSFrame(payload);
|
|
363
|
+
agentConn.socket.write(frame);
|
|
364
|
+
}
|
|
365
|
+
catch (err) {
|
|
366
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
367
|
+
logger.warn(`Failed to forward to agent ${agentId}: ${message} / 轉發失敗`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// ---------------------------------------------------------------------------
|
|
371
|
+
// WebSocket helpers / WebSocket 輔助函數
|
|
372
|
+
// ---------------------------------------------------------------------------
|
|
373
|
+
/** Complete the WebSocket handshake / 完成 WebSocket 交握 */
|
|
374
|
+
completeHandshake(req, socket) {
|
|
375
|
+
const key = req.headers['sec-websocket-key'];
|
|
376
|
+
if (!key) {
|
|
377
|
+
logger.warn('Missing Sec-WebSocket-Key header / 缺少 Sec-WebSocket-Key 標頭');
|
|
378
|
+
socket.write('HTTP/1.1 400 Bad Request\r\n\r\n');
|
|
379
|
+
socket.destroy();
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
const acceptKey = createHash('sha1')
|
|
383
|
+
.update(key + WS_MAGIC_GUID)
|
|
384
|
+
.digest('base64');
|
|
385
|
+
socket.write('HTTP/1.1 101 Switching Protocols\r\n' +
|
|
386
|
+
'Upgrade: websocket\r\n' +
|
|
387
|
+
'Connection: Upgrade\r\n' +
|
|
388
|
+
`Sec-WebSocket-Accept: ${acceptKey}\r\n` +
|
|
389
|
+
'\r\n');
|
|
390
|
+
return true;
|
|
391
|
+
}
|
|
392
|
+
/** Create a WebSocket text frame (unmasked, server->client) / 建立 WebSocket 文字框架 */
|
|
393
|
+
createWSFrame(payload) {
|
|
394
|
+
const length = payload.length;
|
|
395
|
+
let header;
|
|
396
|
+
if (length < 126) {
|
|
397
|
+
header = Buffer.alloc(2);
|
|
398
|
+
header[0] = 0x81; // FIN + text opcode
|
|
399
|
+
header[1] = length;
|
|
400
|
+
}
|
|
401
|
+
else if (length < 65536) {
|
|
402
|
+
header = Buffer.alloc(4);
|
|
403
|
+
header[0] = 0x81;
|
|
404
|
+
header[1] = 126;
|
|
405
|
+
header.writeUInt16BE(length, 2);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
header = Buffer.alloc(10);
|
|
409
|
+
header[0] = 0x81;
|
|
410
|
+
header[1] = 127;
|
|
411
|
+
header.writeBigUInt64BE(BigInt(length), 2);
|
|
412
|
+
}
|
|
413
|
+
return Buffer.concat([header, payload]);
|
|
414
|
+
}
|
|
415
|
+
/** Extract payload from a WebSocket frame (handles both masked and unmasked) / 提取 WebSocket 框架載荷 */
|
|
416
|
+
extractPayload(data) {
|
|
417
|
+
if (data.length < 2)
|
|
418
|
+
return null;
|
|
419
|
+
const secondByte = data[1] ?? 0;
|
|
420
|
+
const masked = (secondByte & 0x80) !== 0;
|
|
421
|
+
let payloadLength = secondByte & 0x7f;
|
|
422
|
+
let offset = 2;
|
|
423
|
+
if (payloadLength === 126) {
|
|
424
|
+
if (data.length < 4)
|
|
425
|
+
return null;
|
|
426
|
+
payloadLength = data.readUInt16BE(2);
|
|
427
|
+
offset = 4;
|
|
428
|
+
}
|
|
429
|
+
else if (payloadLength === 127) {
|
|
430
|
+
if (data.length < 10)
|
|
431
|
+
return null;
|
|
432
|
+
payloadLength = Number(data.readBigUInt64BE(2));
|
|
433
|
+
offset = 10;
|
|
434
|
+
}
|
|
435
|
+
if (masked) {
|
|
436
|
+
if (data.length < offset + 4 + payloadLength)
|
|
437
|
+
return null;
|
|
438
|
+
const maskKey = data.subarray(offset, offset + 4);
|
|
439
|
+
offset += 4;
|
|
440
|
+
const payload = Buffer.alloc(payloadLength);
|
|
441
|
+
for (let i = 0; i < payloadLength; i++) {
|
|
442
|
+
payload[i] = (data[offset + i] ?? 0) ^ (maskKey[i % 4] ?? 0);
|
|
443
|
+
}
|
|
444
|
+
return payload;
|
|
445
|
+
}
|
|
446
|
+
if (data.length < offset + payloadLength)
|
|
447
|
+
return null;
|
|
448
|
+
return data.subarray(offset, offset + payloadLength);
|
|
449
|
+
}
|
|
450
|
+
/** Send a pong frame / 發送 pong 框架 */
|
|
451
|
+
sendPong(socket) {
|
|
452
|
+
if (!socket)
|
|
453
|
+
return;
|
|
454
|
+
try {
|
|
455
|
+
const pong = Buffer.alloc(2);
|
|
456
|
+
pong[0] = 0x8a; // FIN + pong
|
|
457
|
+
pong[1] = 0x00; // 0 payload
|
|
458
|
+
socket.write(pong);
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
/* ignore */
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
//# sourceMappingURL=dashboard-relay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-relay.js","sourceRoot":"","sources":["../src/dashboard-relay.ts"],"names":[],"mappings":"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"}
|