From ef5e5ff005bc281ad19d0fe7336d5ce96666bb92 Mon Sep 17 00:00:00 2001 From: Guillaume Chau Date: Mon, 26 Sep 2022 19:41:01 +0200 Subject: [PATCH] fix: reconnect automatically in case background script is killed, fix #1950 --- packages/app-backend-core/src/index.ts | 4 ++- packages/shared-utils/src/consts.ts | 2 ++ packages/shell-chrome/src/backend.js | 1 + packages/shell-chrome/src/devtools.js | 50 +++++++++++++++++++++----- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/packages/app-backend-core/src/index.ts b/packages/app-backend-core/src/index.ts index 48ca67001..ec177385d 100644 --- a/packages/app-backend-core/src/index.ts +++ b/packages/app-backend-core/src/index.ts @@ -61,7 +61,7 @@ export async function initBackend (bridge: Bridge) { initOnPageConfig() if (!connected) { - // connected = false + // First connect ctx = target.__vdevtools_ctx = createBackendContext({ bridge, hook, @@ -91,8 +91,10 @@ export async function initBackend (bridge: Bridge) { }) } } else { + // Reconnect ctx.bridge = bridge connectBridge() + ctx.bridge.send(BridgeEvents.TO_FRONT_RECONNECTED) } } diff --git a/packages/shared-utils/src/consts.ts b/packages/shared-utils/src/consts.ts index 2f7d95cf3..acf619920 100644 --- a/packages/shared-utils/src/consts.ts +++ b/packages/shared-utils/src/consts.ts @@ -18,6 +18,8 @@ export enum BridgeEvents { /** Tab was switched */ TO_BACK_TAB_SWITCH = 'b:tab:switch', TO_BACK_LOG = 'b:log', + /** Reconnected after background script is terminated (idle) */ + TO_FRONT_RECONNECTED = 'f:reconnected', // Apps /** App was registered */ diff --git a/packages/shell-chrome/src/backend.js b/packages/shell-chrome/src/backend.js index 1017ba175..aaef7540e 100644 --- a/packages/shell-chrome/src/backend.js +++ b/packages/shell-chrome/src/backend.js @@ -44,6 +44,7 @@ function handshake (e) { window.removeEventListener('message', l) }) listeners = [] + window.addEventListener('message', handshake) }) initBackend(bridge) diff --git a/packages/shell-chrome/src/devtools.js b/packages/shell-chrome/src/devtools.js index 7382daf74..88ce82d27 100644 --- a/packages/shell-chrome/src/devtools.js +++ b/packages/shell-chrome/src/devtools.js @@ -1,7 +1,7 @@ // this script is called when the VueDevtools panel is activated. import { initDevTools, setAppConnected } from '@front' -import { Bridge } from '@vue-devtools/shared-utils' +import { Bridge, BridgeEvents } from '@vue-devtools/shared-utils' initDevTools({ @@ -15,18 +15,47 @@ initDevTools({ // 1. inject backend code into page injectScript(chrome.runtime.getURL('build/backend.js'), () => { // 2. connect to background to setup proxy - const port = chrome.runtime.connect({ - name: '' + chrome.devtools.inspectedWindow.tabId, - }) + let port let disconnected = false - port.onDisconnect.addListener(() => { - disconnected = true - setAppConnected(false) - }) + let connectCount = 0 + let timer + + const onMessageHandlers = [] + + function connect () { + try { + clearTimeout(timer) + connectCount++ + port = chrome.runtime.connect({ + name: '' + chrome.devtools.inspectedWindow.tabId, + }) + disconnected = false + port.onDisconnect.addListener(() => { + disconnected = true + setAppConnected(false) + + // Retry + timer = setTimeout(connect, 1000) + }) + + if (connectCount > 1) { + onMessageHandlers.forEach(fn => port.onMessage.addListener(fn)) + } + } catch (e) { + console.error(e) + disconnected = true + setAppConnected(false) + + // Retry + timer = setTimeout(connect, 5000) + } + } + connect() const bridge = new Bridge({ listen (fn) { port.onMessage.addListener(fn) + onMessageHandlers.push(fn) }, send (data) { if (!disconnected) { @@ -37,6 +66,11 @@ initDevTools({ } }, }) + + bridge.on(BridgeEvents.TO_FRONT_RECONNECTED, () => { + setAppConnected(true) + }) + // 3. send a proxy API to the panel cb(bridge) })