cdp-tunnel 2.3.0 → 2.4.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/cli/index.js +3 -2
- package/extension-new/background.js +2 -1
- package/extension-new/cdp/handler/forward.js +2 -2
- package/extension-new/cdp/handler/special.js +2 -1
- package/extension-new/cdp/index.js +4 -4
- package/extension-new/core/debugger.js +1 -0
- package/extension-new/core/state.js +5 -0
- package/extension-new/core/websocket.js +45 -18
- package/extension-new/manifest.json +1 -1
- package/package.json +1 -1
- package/server/proxy-server.js +14 -0
package/cli/index.js
CHANGED
|
@@ -456,8 +456,9 @@ program
|
|
|
456
456
|
|
|
457
457
|
if (wasRunning) {
|
|
458
458
|
log('cyan', '🔄 重启服务器...');
|
|
459
|
-
startServer(savedPort,
|
|
460
|
-
|
|
459
|
+
const child = startServer(savedPort, false, config.autoRestart);
|
|
460
|
+
child.unref();
|
|
461
|
+
log('green', '✅ 服务器已重启 (PID: ' + child.pid + ')');
|
|
461
462
|
} else {
|
|
462
463
|
log('cyan', ' 运行 cdp-tunnel start 启动服务器');
|
|
463
464
|
}
|
|
@@ -124,11 +124,11 @@ importScripts('features/automation-badge.js');
|
|
|
124
124
|
var sessionId = State.findSessionByTabId(tabId);
|
|
125
125
|
if (sessionId) {
|
|
126
126
|
var targetId = State.getTargetIdBySession(sessionId);
|
|
127
|
-
EventBuilder.send('Target.targetDestroyed', { targetId: targetId });
|
|
128
127
|
EventBuilder.send('Target.detachedFromTarget', {
|
|
129
128
|
sessionId: sessionId,
|
|
130
129
|
targetId: targetId
|
|
131
130
|
});
|
|
131
|
+
EventBuilder.send('Target.targetDestroyed', { targetId: targetId });
|
|
132
132
|
State.unmapSession(sessionId);
|
|
133
133
|
if (removedClientId) {
|
|
134
134
|
SpecialHandler.updateTabGroupName(removedClientId);
|
|
@@ -138,6 +138,7 @@ importScripts('features/automation-badge.js');
|
|
|
138
138
|
if (State.getCurrentTabId() === tabId) {
|
|
139
139
|
State.persist(null, false);
|
|
140
140
|
}
|
|
141
|
+
State.removeTabIdToClientId(tabId);
|
|
141
142
|
});
|
|
142
143
|
|
|
143
144
|
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
|
|
@@ -9,12 +9,12 @@ var ForwardHandler = (function() {
|
|
|
9
9
|
|
|
10
10
|
if (!tabId) {
|
|
11
11
|
Logger.warn('[Forward] No tabId for command:', method);
|
|
12
|
-
return Promise.
|
|
12
|
+
return Promise.reject({ code: -32000, message: 'No target found for command: ' + method });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
if (!State.isTabAttached(tabId)) {
|
|
16
16
|
Logger.warn('[Forward] Tab not attached, skipping command:', method, 'tabId:', tabId);
|
|
17
|
-
return Promise.
|
|
17
|
+
return Promise.reject({ code: -32000, message: 'Target is not attached' });
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
Logger.debug('[Forward]', method, '-> tabId:', tabId);
|
|
@@ -228,16 +228,17 @@ var SpecialHandler = (function() {
|
|
|
228
228
|
if (targetId) {
|
|
229
229
|
var tabId = State.getTabIdByTargetId(targetId);
|
|
230
230
|
if (tabId) {
|
|
231
|
-
State.removeAttachedTab(tabId);
|
|
232
231
|
var closeClientId = State.getClientIdByTabId(tabId);
|
|
233
232
|
return new Promise(function(resolve) {
|
|
234
233
|
chrome.tabs.remove(tabId, function() {
|
|
234
|
+
State.removeAttachedTab(tabId);
|
|
235
235
|
if (closeClientId) {
|
|
236
236
|
updateTabGroupName(closeClientId);
|
|
237
237
|
}
|
|
238
238
|
resolve({ success: true });
|
|
239
239
|
});
|
|
240
240
|
}).catch(function() {
|
|
241
|
+
State.removeAttachedTab(tabId);
|
|
241
242
|
return { success: true };
|
|
242
243
|
});
|
|
243
244
|
}
|
|
@@ -82,8 +82,8 @@ function routeCDPCommand(message) {
|
|
|
82
82
|
resolve({ result: result });
|
|
83
83
|
})
|
|
84
84
|
.catch(function(error) {
|
|
85
|
-
Logger.error('[CDP] ERROR id=' + id + ' method=' + method + ' msg=' + error.message);
|
|
86
|
-
resolve({ error: { message: error.message } });
|
|
85
|
+
Logger.error('[CDP] ERROR id=' + id + ' method=' + method + ' msg=' + (error.message || error));
|
|
86
|
+
resolve({ error: { code: error.code || -32000, message: error.message || String(error) } });
|
|
87
87
|
});
|
|
88
88
|
} else {
|
|
89
89
|
ForwardHandler.execute({ id: id, method: method, params: params, sessionId: sessionId, clientId: clientId })
|
|
@@ -92,8 +92,8 @@ function routeCDPCommand(message) {
|
|
|
92
92
|
resolve({ result: result });
|
|
93
93
|
})
|
|
94
94
|
.catch(function(error) {
|
|
95
|
-
Logger.error('[CDP] ERROR id=' + id + ' method=' + method + ' msg=' + error.message + ' (forwarded)');
|
|
96
|
-
resolve({ error: { message: error.message } });
|
|
95
|
+
Logger.error('[CDP] ERROR id=' + id + ' method=' + method + ' msg=' + (error.message || error) + ' (forwarded)');
|
|
96
|
+
resolve({ error: { code: error.code || -32000, message: error.message || String(error) } });
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
}).then(function(response) {
|
|
@@ -342,6 +342,10 @@ var State = (function() {
|
|
|
342
342
|
_state.tabIdToClientId.set(tabId, clientId);
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
+
function removeTabIdToClientId(tabId) {
|
|
346
|
+
_state.tabIdToClientId.delete(tabId);
|
|
347
|
+
}
|
|
348
|
+
|
|
345
349
|
function getClientIdByTabId(tabId) {
|
|
346
350
|
return _state.tabIdToClientId.get(tabId);
|
|
347
351
|
}
|
|
@@ -481,6 +485,7 @@ var State = (function() {
|
|
|
481
485
|
clearAllState: clearAllState,
|
|
482
486
|
cleanupAllTabs: cleanupAllTabs,
|
|
483
487
|
setTabIdToClientId: setTabIdToClientId,
|
|
488
|
+
removeTabIdToClientId: removeTabIdToClientId,
|
|
484
489
|
getClientIdByTabId: getClientIdByTabId,
|
|
485
490
|
setGroupIdForClient: setGroupIdForClient,
|
|
486
491
|
getGroupIdForClient: getGroupIdForClient,
|
|
@@ -339,16 +339,20 @@ var WebSocketManager = (function() {
|
|
|
339
339
|
return;
|
|
340
340
|
}
|
|
341
341
|
Logger.info('[WS] Closing ' + tabIds.length + ' attached tabs for clientId:', clientId);
|
|
342
|
+
var pending = tabIds.length;
|
|
342
343
|
tabIds.forEach(function(tabId) {
|
|
343
344
|
chrome.tabs.remove(tabId, function() {
|
|
344
345
|
if (chrome.runtime.lastError) {
|
|
345
346
|
Logger.info('[WS] Tab already closed:', tabId);
|
|
346
347
|
}
|
|
348
|
+
chrome.debugger.detach({ tabId: tabId }).catch(function() {});
|
|
349
|
+
State.removeAttachedTab(tabId);
|
|
350
|
+
pending--;
|
|
351
|
+
if (pending === 0) {
|
|
352
|
+
resolve();
|
|
353
|
+
}
|
|
347
354
|
});
|
|
348
|
-
chrome.debugger.detach({ tabId: tabId }).catch(function() {});
|
|
349
|
-
State.removeAttachedTab(tabId);
|
|
350
355
|
});
|
|
351
|
-
resolve();
|
|
352
356
|
}
|
|
353
357
|
|
|
354
358
|
function handleServerRestart() {
|
|
@@ -372,17 +376,27 @@ var WebSocketManager = (function() {
|
|
|
372
376
|
Logger.info('[WS] Browser.close received, cleaning up... clientId:', clientId);
|
|
373
377
|
|
|
374
378
|
closeTabGroupByClientId(clientId).then(function() {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
379
|
+
return new Promise(function(resolve) {
|
|
380
|
+
closeTabsByClientId(clientId, resolve);
|
|
381
|
+
});
|
|
382
|
+
}).then(function() {
|
|
383
|
+
var preExistingTabs = State.getPreExistingTabs();
|
|
384
|
+
var clientPreExisting = preExistingTabs.filter(function(tabId) {
|
|
385
|
+
return State.getClientIdByTabId(tabId) === clientId;
|
|
380
386
|
});
|
|
381
|
-
|
|
387
|
+
clientPreExisting.forEach(function(tabId) {
|
|
388
|
+
chrome.debugger.detach({ tabId: tabId }).catch(function() {});
|
|
389
|
+
State.removeAttachedTab(tabId);
|
|
390
|
+
});
|
|
391
|
+
State.clearPreExistingTabsForClient(clientId);
|
|
392
|
+
|
|
393
|
+
State.removeCDPClient(clientId);
|
|
394
|
+
if (State.getCDPClients().length === 0) {
|
|
382
395
|
State.clearAllState();
|
|
383
396
|
State.persist(null, false);
|
|
384
|
-
|
|
385
|
-
|
|
397
|
+
}
|
|
398
|
+
broadcastStateUpdate();
|
|
399
|
+
Logger.info('[WS] Browser.close cleanup complete for client:', clientId);
|
|
386
400
|
});
|
|
387
401
|
}
|
|
388
402
|
|
|
@@ -398,7 +412,18 @@ var WebSocketManager = (function() {
|
|
|
398
412
|
var cdpClients = State.getCDPClients() || [];
|
|
399
413
|
var attachedTabIds = State.getAttachedTabIds();
|
|
400
414
|
|
|
415
|
+
if (attachedTabIds.length === 0) {
|
|
416
|
+
chrome.runtime.sendMessage({
|
|
417
|
+
type: 'stateUpdate',
|
|
418
|
+
connected: isConnected,
|
|
419
|
+
cdpClients: cdpClients,
|
|
420
|
+
attachedPages: []
|
|
421
|
+
}).catch(function() {});
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
401
425
|
var attachedPages = [];
|
|
426
|
+
var pending = attachedTabIds.length;
|
|
402
427
|
attachedTabIds.forEach(function(tabId) {
|
|
403
428
|
chrome.tabs.get(tabId, function(tab) {
|
|
404
429
|
if (tab && !chrome.runtime.lastError) {
|
|
@@ -408,15 +433,17 @@ var WebSocketManager = (function() {
|
|
|
408
433
|
url: tab.url || ''
|
|
409
434
|
});
|
|
410
435
|
}
|
|
436
|
+
pending--;
|
|
437
|
+
if (pending === 0) {
|
|
438
|
+
chrome.runtime.sendMessage({
|
|
439
|
+
type: 'stateUpdate',
|
|
440
|
+
connected: isConnected,
|
|
441
|
+
cdpClients: cdpClients,
|
|
442
|
+
attachedPages: attachedPages
|
|
443
|
+
}).catch(function() {});
|
|
444
|
+
}
|
|
411
445
|
});
|
|
412
446
|
});
|
|
413
|
-
|
|
414
|
-
chrome.runtime.sendMessage({
|
|
415
|
-
type: 'stateUpdate',
|
|
416
|
-
connected: isConnected,
|
|
417
|
-
cdpClients: cdpClients,
|
|
418
|
-
attachedPages: attachedPages
|
|
419
|
-
}).catch(function() {});
|
|
420
447
|
}
|
|
421
448
|
|
|
422
449
|
function getQueueStats() {
|
package/package.json
CHANGED
package/server/proxy-server.js
CHANGED
|
@@ -1017,6 +1017,20 @@ function handleClientConnection(ws, clientInfo, customClientId = null) {
|
|
|
1017
1017
|
// 广播更新后的客户端列表
|
|
1018
1018
|
broadcastClientList();
|
|
1019
1019
|
|
|
1020
|
+
// 清理该 client 的所有映射
|
|
1021
|
+
for (const [tId, cId] of targetIdToClientId.entries()) {
|
|
1022
|
+
if (cId === id) targetIdToClientId.delete(tId);
|
|
1023
|
+
}
|
|
1024
|
+
for (const [bcId, cId] of browserContextToClientId.entries()) {
|
|
1025
|
+
if (cId === id) browserContextToClientId.delete(bcId);
|
|
1026
|
+
}
|
|
1027
|
+
if (clientIdToBrowserContext.has(id)) {
|
|
1028
|
+
clientIdToBrowserContext.delete(id);
|
|
1029
|
+
}
|
|
1030
|
+
for (const [gId, mapping] of globalRequestIdMap.entries()) {
|
|
1031
|
+
if (mapping.clientId === id) globalRequestIdMap.delete(gId);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1020
1034
|
// 清理配对关系
|
|
1021
1035
|
if (ws.pairedPlugin) {
|
|
1022
1036
|
ws.pairedPlugin.pairedClientId = null;
|