cdp-tunnel 2.7.9 → 2.8.0
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/extension-new/background.js +234 -130
- package/extension-new/cdp/handler/forward.js +9 -7
- package/extension-new/cdp/handler/local.js +60 -39
- package/extension-new/cdp/handler/special.js +145 -119
- package/extension-new/cdp/index.js +16 -7
- package/extension-new/cdp/response.js +12 -4
- package/extension-new/config-page-preview.html +174 -57
- package/extension-new/config-page.js +169 -70
- package/extension-new/core/connection-manager.js +120 -0
- package/extension-new/core/connection-state.js +355 -0
- package/extension-new/core/debugger.js +65 -52
- package/extension-new/core/state.js +87 -438
- package/extension-new/core/websocket.js +345 -279
- package/extension-new/features/screencast.js +42 -20
- package/extension-new/manifest.json +3 -2
- package/extension-new/utils/config.js +83 -2
- package/extension-new/utils/helpers.js +5 -4
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
var state = {
|
|
3
3
|
connected: false,
|
|
4
|
-
serverAddress: 'ws://localhost:9221/plugin',
|
|
5
4
|
cdpClients: [],
|
|
6
5
|
attachedPages: [],
|
|
7
6
|
logs: [],
|
|
8
7
|
startTime: Date.now(),
|
|
9
|
-
cdpCommandCount: 0
|
|
8
|
+
cdpCommandCount: 0,
|
|
9
|
+
connectionStatuses: {}
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
var elements = {
|
|
@@ -21,10 +21,14 @@
|
|
|
21
21
|
clientList: document.getElementById('clientList'),
|
|
22
22
|
pageList: document.getElementById('pageList'),
|
|
23
23
|
activityLog: document.getElementById('activityLog'),
|
|
24
|
-
serverAddress: document.getElementById('serverAddress'),
|
|
25
|
-
connectBtn: document.getElementById('connectBtn'),
|
|
26
24
|
refreshBtn: document.getElementById('refreshBtn'),
|
|
27
|
-
toast: document.getElementById('toast')
|
|
25
|
+
toast: document.getElementById('toast'),
|
|
26
|
+
connConfigList: document.getElementById('connConfigList'),
|
|
27
|
+
newConnTag: document.getElementById('newConnTag'),
|
|
28
|
+
newConnUrl: document.getElementById('newConnUrl'),
|
|
29
|
+
addConnBtn: document.getElementById('addConnBtn'),
|
|
30
|
+
autoMuteToggle: document.getElementById('autoMuteToggle'),
|
|
31
|
+
pluginIdDisplay: document.getElementById('pluginIdDisplay')
|
|
28
32
|
};
|
|
29
33
|
|
|
30
34
|
function showToast(message, type) {
|
|
@@ -53,7 +57,7 @@
|
|
|
53
57
|
elements.activeConnections.textContent = state.cdpClients.length;
|
|
54
58
|
elements.controlledPages.textContent = state.attachedPages.length;
|
|
55
59
|
elements.cdpCommands.textContent = state.cdpCommandCount;
|
|
56
|
-
|
|
60
|
+
|
|
57
61
|
var elapsed = Math.floor((Date.now() - state.startTime) / 1000);
|
|
58
62
|
if (elapsed < 60) {
|
|
59
63
|
elements.uptime.textContent = elapsed + 's';
|
|
@@ -62,14 +66,51 @@
|
|
|
62
66
|
} else {
|
|
63
67
|
elements.uptime.textContent = Math.floor(elapsed / 3600) + 'h ' + Math.floor((elapsed % 3600) / 60) + 'm';
|
|
64
68
|
}
|
|
65
|
-
|
|
69
|
+
|
|
66
70
|
elements.clientCount.textContent = state.cdpClients.length + ' 个';
|
|
67
71
|
elements.pageCount.textContent = state.attachedPages.length + ' 个';
|
|
68
72
|
}
|
|
69
73
|
|
|
74
|
+
function getStatusClass(connId, enabled) {
|
|
75
|
+
if (!enabled) return 'disabled';
|
|
76
|
+
var s = state.connectionStatuses[connId];
|
|
77
|
+
if (s === 'connected') return 'connected';
|
|
78
|
+
if (s === 'error') return 'error';
|
|
79
|
+
return 'disabled';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function renderConnections(connections) {
|
|
83
|
+
if (!connections || connections.length === 0) {
|
|
84
|
+
elements.connConfigList.innerHTML =
|
|
85
|
+
'<div class="empty-state">' +
|
|
86
|
+
'<div class="icon">🔗</div>' +
|
|
87
|
+
'<div class="title">暂无连接配置</div>' +
|
|
88
|
+
'<div class="desc">在下方添加一个 WebSocket 连接</div>' +
|
|
89
|
+
'</div>';
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
var html = '';
|
|
94
|
+
connections.forEach(function(conn) {
|
|
95
|
+
var statusClass = getStatusClass(conn.id, conn.enabled);
|
|
96
|
+
var isActive = conn.enabled && statusClass === 'connected';
|
|
97
|
+
html +=
|
|
98
|
+
'<div class="conn-config-item' + (isActive ? ' active' : '') + '" data-id="' + conn.id + '">' +
|
|
99
|
+
'<input type="checkbox" class="conn-toggle" data-id="' + conn.id + '"' + (conn.enabled ? ' checked' : '') + ' title="启用/禁用">' +
|
|
100
|
+
'<span class="status-dot ' + statusClass + '" title="' + statusClass + '"></span>' +
|
|
101
|
+
'<div class="conn-config-info">' +
|
|
102
|
+
'<div class="conn-config-tag">' + escapeHtml(conn.tag) + '</div>' +
|
|
103
|
+
'<div class="conn-config-url" title="' + escapeAttr(conn.url) + '">' + escapeHtml(conn.url) + '</div>' +
|
|
104
|
+
'</div>' +
|
|
105
|
+
'<button class="btn-delete" data-id="' + conn.id + '" title="删除">删除</button>' +
|
|
106
|
+
'</div>';
|
|
107
|
+
});
|
|
108
|
+
elements.connConfigList.innerHTML = html;
|
|
109
|
+
}
|
|
110
|
+
|
|
70
111
|
function renderClients() {
|
|
71
112
|
if (state.cdpClients.length === 0) {
|
|
72
|
-
elements.clientList.innerHTML =
|
|
113
|
+
elements.clientList.innerHTML =
|
|
73
114
|
'<div class="empty-state">' +
|
|
74
115
|
'<div class="icon">🔌</div>' +
|
|
75
116
|
'<div class="title">暂无客户端</div>' +
|
|
@@ -83,8 +124,8 @@
|
|
|
83
124
|
var clientId = client.id || '';
|
|
84
125
|
var shortId = clientId.length > 25 ? clientId.substring(0, 25) + '...' : clientId;
|
|
85
126
|
var connectedAt = client.connectedAt ? new Date(client.connectedAt).toLocaleTimeString() : 'N/A';
|
|
86
|
-
|
|
87
|
-
html +=
|
|
127
|
+
|
|
128
|
+
html +=
|
|
88
129
|
'<div class="connection-item active">' +
|
|
89
130
|
'<div class="status-indicator online"></div>' +
|
|
90
131
|
'<div class="connection-info">' +
|
|
@@ -93,8 +134,8 @@
|
|
|
93
134
|
'<span class="connection-tag playwright">CDP</span>' +
|
|
94
135
|
'</div>' +
|
|
95
136
|
'<div class="connection-details">' +
|
|
96
|
-
'<span
|
|
97
|
-
'<span
|
|
137
|
+
'<span>Playwright/Puppeteer</span>' +
|
|
138
|
+
'<span>' + connectedAt + '</span>' +
|
|
98
139
|
'</div>' +
|
|
99
140
|
'</div>' +
|
|
100
141
|
'</div>';
|
|
@@ -104,7 +145,7 @@
|
|
|
104
145
|
|
|
105
146
|
function renderPages() {
|
|
106
147
|
if (state.attachedPages.length === 0) {
|
|
107
|
-
elements.pageList.innerHTML =
|
|
148
|
+
elements.pageList.innerHTML =
|
|
108
149
|
'<div class="empty-state">' +
|
|
109
150
|
'<div class="icon">📄</div>' +
|
|
110
151
|
'<div class="title">暂无页面</div>' +
|
|
@@ -118,8 +159,8 @@
|
|
|
118
159
|
var pageUrl = page.url || '';
|
|
119
160
|
var displayUrl = pageUrl.length > 35 ? pageUrl.substring(0, 35) + '...' : pageUrl;
|
|
120
161
|
var pageTitle = page.title || 'Untitled';
|
|
121
|
-
|
|
122
|
-
html +=
|
|
162
|
+
|
|
163
|
+
html +=
|
|
123
164
|
'<div class="connection-item active">' +
|
|
124
165
|
'<div class="status-indicator online"></div>' +
|
|
125
166
|
'<div class="connection-info">' +
|
|
@@ -141,7 +182,7 @@
|
|
|
141
182
|
|
|
142
183
|
function renderLogs() {
|
|
143
184
|
if (state.logs.length === 0) {
|
|
144
|
-
elements.activityLog.innerHTML =
|
|
185
|
+
elements.activityLog.innerHTML =
|
|
145
186
|
'<div class="empty-state">' +
|
|
146
187
|
'<div class="icon">📋</div>' +
|
|
147
188
|
'<div class="title">暂无日志</div>' +
|
|
@@ -152,7 +193,7 @@
|
|
|
152
193
|
|
|
153
194
|
var html = '';
|
|
154
195
|
state.logs.slice(0, 20).forEach(function(log) {
|
|
155
|
-
html +=
|
|
196
|
+
html +=
|
|
156
197
|
'<div class="log-item">' +
|
|
157
198
|
'<div class="log-icon ' + log.type + '">' + log.icon + '</div>' +
|
|
158
199
|
'<div class="log-content">' +
|
|
@@ -171,14 +212,14 @@
|
|
|
171
212
|
action: '⚡',
|
|
172
213
|
page: '📄'
|
|
173
214
|
};
|
|
174
|
-
|
|
215
|
+
|
|
175
216
|
state.logs.unshift({
|
|
176
217
|
type: type,
|
|
177
218
|
icon: icons[type] || '•',
|
|
178
219
|
message: message,
|
|
179
220
|
time: new Date().toLocaleTimeString()
|
|
180
221
|
});
|
|
181
|
-
|
|
222
|
+
|
|
182
223
|
renderLogs();
|
|
183
224
|
}
|
|
184
225
|
|
|
@@ -189,10 +230,8 @@
|
|
|
189
230
|
chrome.runtime.sendMessage({ type: 'getState' }, function(response) {
|
|
190
231
|
if (response) {
|
|
191
232
|
state.connected = response.connected || false;
|
|
192
|
-
state.serverAddress = response.serverAddress || state.serverAddress;
|
|
193
233
|
state.cdpClients = response.cdpClients || [];
|
|
194
234
|
state.attachedPages = response.attachedPages || [];
|
|
195
|
-
elements.serverAddress.value = state.serverAddress;
|
|
196
235
|
updateStatus(state.connected);
|
|
197
236
|
updateStats();
|
|
198
237
|
renderClients();
|
|
@@ -207,7 +246,7 @@
|
|
|
207
246
|
} catch (e) {
|
|
208
247
|
console.error('[Config] Failed to fetch state:', e);
|
|
209
248
|
}
|
|
210
|
-
|
|
249
|
+
|
|
211
250
|
updateStatus(false);
|
|
212
251
|
updateStats();
|
|
213
252
|
renderClients();
|
|
@@ -216,73 +255,131 @@
|
|
|
216
255
|
});
|
|
217
256
|
}
|
|
218
257
|
|
|
219
|
-
function
|
|
220
|
-
var address = elements.serverAddress.value.trim();
|
|
221
|
-
|
|
222
|
-
if (!address) {
|
|
223
|
-
showToast('请输入服务器地址', 'error');
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
state.serverAddress = address;
|
|
228
|
-
|
|
229
|
-
if (typeof chrome !== 'undefined' && chrome.storage) {
|
|
230
|
-
chrome.storage.local.set({ wsAddress: address });
|
|
231
|
-
}
|
|
232
|
-
|
|
258
|
+
function loadConnectionStatuses() {
|
|
233
259
|
if (typeof chrome !== 'undefined' && chrome.runtime) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
} catch (e) {
|
|
241
|
-
showToast('连接请求发送失败', 'error');
|
|
242
|
-
}
|
|
260
|
+
chrome.runtime.sendMessage({ type: 'get-connection-statuses' }, function(response) {
|
|
261
|
+
if (response && response.statuses) {
|
|
262
|
+
state.connectionStatuses = response.statuses;
|
|
263
|
+
}
|
|
264
|
+
loadAndRenderConnections();
|
|
265
|
+
});
|
|
243
266
|
} else {
|
|
244
|
-
|
|
267
|
+
loadAndRenderConnections();
|
|
245
268
|
}
|
|
246
269
|
}
|
|
247
270
|
|
|
248
|
-
function
|
|
249
|
-
|
|
250
|
-
|
|
271
|
+
function loadAndRenderConnections() {
|
|
272
|
+
if (typeof Config !== 'undefined' && Config.getConnections) {
|
|
273
|
+
Config.getConnections(function(connections) {
|
|
274
|
+
renderConnections(connections);
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function escapeHtml(s) {
|
|
280
|
+
return (s || '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function escapeAttr(s) {
|
|
284
|
+
return (s || '').replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
251
285
|
}
|
|
252
286
|
|
|
253
287
|
function init() {
|
|
254
288
|
if (typeof chrome !== 'undefined' && chrome.storage) {
|
|
255
|
-
chrome.storage.local.get('wsAddress', function(result) {
|
|
256
|
-
if (result.wsAddress) {
|
|
257
|
-
state.serverAddress = result.wsAddress;
|
|
258
|
-
elements.serverAddress.value = result.wsAddress;
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
289
|
chrome.storage.local.get(['autoMute'], function(result) {
|
|
262
|
-
|
|
290
|
+
elements.autoMuteToggle.checked = result.autoMute !== false;
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
Config.getPluginId(function(id) {
|
|
294
|
+
elements.pluginIdDisplay.textContent = id || '-';
|
|
263
295
|
});
|
|
264
296
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
297
|
+
|
|
298
|
+
elements.autoMuteToggle.addEventListener('change', function(e) {
|
|
299
|
+
if (typeof Config !== 'undefined') {
|
|
300
|
+
Config.setAutoMute(e.target.checked);
|
|
301
|
+
}
|
|
302
|
+
addLog('action', e.target.checked ? '自动静音已开启' : '自动静音已关闭');
|
|
269
303
|
});
|
|
270
304
|
|
|
271
305
|
var versionBadge = document.getElementById('versionBadge');
|
|
272
|
-
if (versionBadge) {
|
|
306
|
+
if (versionBadge && typeof chrome !== 'undefined' && chrome.runtime) {
|
|
273
307
|
var manifest = chrome.runtime.getManifest();
|
|
274
308
|
versionBadge.textContent = 'v' + manifest.version;
|
|
275
309
|
}
|
|
276
|
-
|
|
310
|
+
|
|
311
|
+
loadConnectionStatuses();
|
|
277
312
|
fetchState();
|
|
278
|
-
|
|
279
|
-
setInterval(
|
|
313
|
+
|
|
314
|
+
setInterval(function() {
|
|
315
|
+
fetchState();
|
|
316
|
+
loadConnectionStatuses();
|
|
317
|
+
}, 5000);
|
|
280
318
|
setInterval(updateStats, 1000);
|
|
281
319
|
}
|
|
282
320
|
|
|
283
|
-
elements.
|
|
284
|
-
|
|
285
|
-
|
|
321
|
+
elements.addConnBtn.addEventListener('click', function() {
|
|
322
|
+
var tag = elements.newConnTag.value.trim();
|
|
323
|
+
var url = elements.newConnUrl.value.trim();
|
|
324
|
+
|
|
325
|
+
if (!tag) {
|
|
326
|
+
showToast('请输入连接名称', 'error');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (!url) {
|
|
330
|
+
showToast('请输入 WebSocket 地址', 'error');
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (typeof chrome !== 'undefined' && chrome.runtime) {
|
|
335
|
+
chrome.runtime.sendMessage({ type: 'add-connection', tag: tag, url: url }, function() {
|
|
336
|
+
elements.newConnTag.value = '';
|
|
337
|
+
elements.newConnUrl.value = '';
|
|
338
|
+
loadAndRenderConnections();
|
|
339
|
+
showToast('连接已添加');
|
|
340
|
+
});
|
|
341
|
+
} else if (typeof Config !== 'undefined') {
|
|
342
|
+
Config.addConnection({ tag: tag, url: url }, function() {
|
|
343
|
+
elements.newConnTag.value = '';
|
|
344
|
+
elements.newConnUrl.value = '';
|
|
345
|
+
loadAndRenderConnections();
|
|
346
|
+
showToast('连接已添加');
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
elements.connConfigList.addEventListener('click', function(e) {
|
|
352
|
+
var toggleEl = e.target.closest('.conn-toggle');
|
|
353
|
+
if (toggleEl) {
|
|
354
|
+
var connId = toggleEl.dataset.id;
|
|
355
|
+
var enabled = toggleEl.checked;
|
|
356
|
+
if (typeof chrome !== 'undefined' && chrome.runtime) {
|
|
357
|
+
chrome.runtime.sendMessage({ type: 'toggle-connection', connectionId: connId, enabled: enabled }, function() {
|
|
358
|
+
loadAndRenderConnections();
|
|
359
|
+
showToast(enabled ? '连接已启用' : '连接已禁用');
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
var deleteBtn = e.target.closest('.btn-delete');
|
|
366
|
+
if (deleteBtn) {
|
|
367
|
+
var deleteId = deleteBtn.dataset.id;
|
|
368
|
+
if (typeof chrome !== 'undefined' && chrome.runtime) {
|
|
369
|
+
chrome.runtime.sendMessage({ type: 'remove-connection', connectionId: deleteId }, function() {
|
|
370
|
+
loadAndRenderConnections();
|
|
371
|
+
showToast('连接已删除');
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
elements.refreshBtn.addEventListener('click', function() {
|
|
378
|
+
fetchState();
|
|
379
|
+
loadConnectionStatuses();
|
|
380
|
+
showToast('已刷新');
|
|
381
|
+
});
|
|
382
|
+
|
|
286
383
|
elements.pageList.addEventListener('click', function(e) {
|
|
287
384
|
var btn = e.target.closest('.action-btn');
|
|
288
385
|
if (btn) {
|
|
@@ -299,7 +396,7 @@
|
|
|
299
396
|
});
|
|
300
397
|
|
|
301
398
|
if (typeof chrome !== 'undefined' && chrome.runtime) {
|
|
302
|
-
chrome.runtime.onMessage.addListener(function(message
|
|
399
|
+
chrome.runtime.onMessage.addListener(function(message) {
|
|
303
400
|
if (message.type === 'stateUpdate') {
|
|
304
401
|
var wasConnected = state.connected;
|
|
305
402
|
state.connected = message.connected;
|
|
@@ -309,13 +406,13 @@
|
|
|
309
406
|
updateStats();
|
|
310
407
|
renderClients();
|
|
311
408
|
renderPages();
|
|
312
|
-
|
|
409
|
+
|
|
313
410
|
if (state.connected && !wasConnected) {
|
|
314
411
|
addLog('connect', '已连接到服务器');
|
|
315
412
|
} else if (!state.connected && wasConnected) {
|
|
316
413
|
addLog('disconnect', '已断开连接');
|
|
317
414
|
}
|
|
318
|
-
|
|
415
|
+
|
|
319
416
|
if (state.cdpClients.length > 0) {
|
|
320
417
|
addLog('connect', state.cdpClients.length + ' 个 CDP 客户端在线');
|
|
321
418
|
}
|
|
@@ -324,6 +421,8 @@
|
|
|
324
421
|
}
|
|
325
422
|
} else if (message.type === 'log') {
|
|
326
423
|
addLog(message.logType, message.message);
|
|
424
|
+
} else if (message.type === 'connections-updated') {
|
|
425
|
+
loadAndRenderConnections();
|
|
327
426
|
}
|
|
328
427
|
});
|
|
329
428
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
var ConnectionManager = (function() {
|
|
2
|
+
var _connections = new Map();
|
|
3
|
+
|
|
4
|
+
function init(connectionConfigs) {
|
|
5
|
+
var enabled = (connectionConfigs || []).filter(function(c) { return c.enabled; });
|
|
6
|
+
if (enabled.length === 0) {
|
|
7
|
+
enabled.push({
|
|
8
|
+
id: 'conn_default',
|
|
9
|
+
tag: 'default',
|
|
10
|
+
url: Config.WS_URL,
|
|
11
|
+
enabled: true
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
enabled.forEach(function(config) {
|
|
15
|
+
addConnection(config);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function addConnection(config) {
|
|
20
|
+
if (!config || !config.id) return;
|
|
21
|
+
if (_connections.has(config.id)) {
|
|
22
|
+
Logger.warn('[CM] Connection already exists:', config.id);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var state = new ConnectionState(config.id);
|
|
27
|
+
var wsManager = new WebSocketConnection(config.id, state, config);
|
|
28
|
+
|
|
29
|
+
_connections.set(config.id, {
|
|
30
|
+
id: config.id,
|
|
31
|
+
config: config,
|
|
32
|
+
state: state,
|
|
33
|
+
wsManager: wsManager
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
Logger.info('[CM] Added connection:', config.id, config.url);
|
|
37
|
+
return wsManager;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function removeConnection(connectionId) {
|
|
41
|
+
var entry = _connections.get(connectionId);
|
|
42
|
+
if (!entry) return;
|
|
43
|
+
|
|
44
|
+
entry.state.clearReconnectTimer();
|
|
45
|
+
if (entry.state.ws) {
|
|
46
|
+
try { entry.state.ws.close(); } catch(e) {}
|
|
47
|
+
}
|
|
48
|
+
entry.state.clearAllState();
|
|
49
|
+
_connections.delete(connectionId);
|
|
50
|
+
Logger.info('[CM] Removed connection:', connectionId);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getConnection(connectionId) {
|
|
54
|
+
return _connections.get(connectionId);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function getConnectionByTabId(tabId) {
|
|
58
|
+
var result = null;
|
|
59
|
+
_connections.forEach(function(entry) {
|
|
60
|
+
if (entry.state.isTabAttached(tabId) || entry.state.tabIdToClientId.has(tabId)) {
|
|
61
|
+
result = entry;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getConnectionBySessionId(sessionId) {
|
|
68
|
+
var result = null;
|
|
69
|
+
_connections.forEach(function(entry) {
|
|
70
|
+
if (entry.state.sessionIdToTabId.has(sessionId)) {
|
|
71
|
+
result = entry;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getAllConnections() {
|
|
78
|
+
return Array.from(_connections.values());
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function forEachConnection(callback) {
|
|
82
|
+
_connections.forEach(function(entry, id) {
|
|
83
|
+
callback(entry, id);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function getPrimaryConnection() {
|
|
88
|
+
var first = _connections.values().next();
|
|
89
|
+
return first.done ? null : first.value;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function connectAll() {
|
|
93
|
+
_connections.forEach(function(entry) {
|
|
94
|
+
entry.wsManager.connect();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function disconnectAll() {
|
|
99
|
+
_connections.forEach(function(entry) {
|
|
100
|
+
if (entry.state.ws) {
|
|
101
|
+
try { entry.state.ws.close(); } catch(e) {}
|
|
102
|
+
}
|
|
103
|
+
entry.state.clearReconnectTimer();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
init: init,
|
|
109
|
+
addConnection: addConnection,
|
|
110
|
+
removeConnection: removeConnection,
|
|
111
|
+
getConnection: getConnection,
|
|
112
|
+
getConnectionByTabId: getConnectionByTabId,
|
|
113
|
+
getConnectionBySessionId: getConnectionBySessionId,
|
|
114
|
+
getAllConnections: getAllConnections,
|
|
115
|
+
forEachConnection: forEachConnection,
|
|
116
|
+
getPrimaryConnection: getPrimaryConnection,
|
|
117
|
+
connectAll: connectAll,
|
|
118
|
+
disconnectAll: disconnectAll
|
|
119
|
+
};
|
|
120
|
+
})();
|