Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the issue that the TCP connection was interrupted when setting a proxy #9708

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions app/electron/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ app.whenReady().then(() => {
event.sender.send("siyuan-event", "leave-full-screen");
});
});
ipcMain.on("siyuan-cmd", (event, data) => {
ipcMain.on("siyuan-cmd", async (event, data) => {
let cmd = data;
let webContentsId = event.sender.id;
if (typeof data !== "string") {
Expand Down Expand Up @@ -820,17 +820,29 @@ app.whenReady().then(() => {
}
break;
case "setProxy":
event.sender.session.closeAllConnections().then(() => {
try {
let proxy, log;
if (data.proxyURL.startsWith("://")) {
event.sender.session.setProxy({mode: "system"}).then(() => {
console.log("network proxy [system]");
});
return;
proxy = {mode: "system"};
log = "network proxy [system]";
} else {
proxy = {proxyRules: data.proxyURL};
log = `network proxy [${data.proxyURL}]`;
}
event.sender.session.setProxy({proxyRules: data.proxyURL}).then(() => {
console.log("network proxy [" + data.proxyURL + "]");
await event.sender.session.closeAllConnections();
await event.sender.session.setProxy(proxy);
console.log(log);
event.reply("siyuan-proxy-reply", {
state: "fulfilled",
proxy,
});
});
} catch (error) {
event.reply("siyuan-proxy-reply", {
state: "rejected",
proxy,
error,
});
}
break;
}
});
Expand Down
2 changes: 0 additions & 2 deletions app/src/boot/onGetConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {showMessage} from "../dialog/message";
import {replaceLocalPath} from "../editor/rename";
import {setTabPosition} from "../window/setHeader";
import {initBar} from "../layout/topBar";
import {setProxy} from "../config/util/about";
import {openChangelog} from "./openChangelog";
import {getIdFromSYProtocol, isSYProtocol} from "../util/pathName";
import {App} from "../index";
Expand Down Expand Up @@ -135,7 +134,6 @@ export const onGetConfig = (isStart: boolean, app: App) => {
}
});
initBar(app);
setProxy();
initStatus();
initWindow(app);
appearance.onSetappearance(window.siyuan.config.appearance);
Expand Down
25 changes: 22 additions & 3 deletions app/src/config/util/about.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,28 @@ import {Constants} from "../../constants";

export const setProxy = () => {
/// #if !BROWSER
ipcRenderer.send(Constants.SIYUAN_CMD, {
cmd: "setProxy",
proxyURL: `${window.siyuan.config.system.networkProxy.scheme}://${window.siyuan.config.system.networkProxy.host}:${window.siyuan.config.system.networkProxy.port}`
return new Promise((resolve, reject) => {
ipcRenderer.once(Constants.SIYUAN_PROXY_REPLY, (event, data: {
state: "fulfilled" | "rejected",
proxy: {mode: "system"} | {proxyRules: string},
error?: any,
}) => {
switch (data.state) {
case "fulfilled":
resolve(data.proxy);
break;
case "rejected":
reject(data.error);
break;
default:
reject(new Error(`Unknown state: ${data.state}`));
break;
}
});
ipcRenderer.send(Constants.SIYUAN_CMD, {
cmd: "setProxy",
proxyURL: `${window.siyuan.config.system.networkProxy.scheme}://${window.siyuan.config.system.networkProxy.host}:${window.siyuan.config.system.networkProxy.port}`
});
});
/// #endif
};
Expand Down
2 changes: 2 additions & 0 deletions app/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export abstract class Constants {
public static readonly SIYUAN_GET: string = "siyuan-get";
public static readonly SIYUAN_EVENT: string = "siyuan-event";

public static readonly SIYUAN_PROXY_REPLY: string = "siyuan-proxy-reply";

public static readonly SIYUAN_CONFIG_TRAY: string = "siyuan-config-tray";
public static readonly SIYUAN_QUIT: string = "siyuan-quit";
public static readonly SIYUAN_HOTKEY: string = "siyuan-hotkey";
Expand Down
20 changes: 13 additions & 7 deletions app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Model} from "./layout/Model";
import {onGetConfig} from "./boot/onGetConfig";
import {initBlockPopover} from "./block/popover";
import {account} from "./config/account";
import {setProxy} from "./config/util/about";
import {addScript, addScriptSync} from "./protyle/util/addScript";
import {genUUID} from "./util/genID";
import {fetchGet, fetchPost} from "./util/fetch";
Expand Down Expand Up @@ -33,11 +34,6 @@ export class App {
public appId: string;

constructor() {
/// #if BROWSER
registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
/// #endif
addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript");
addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript");
addBaseURL();

this.appId = Constants.SIYUAN_APPID;
Expand Down Expand Up @@ -161,6 +157,18 @@ export class App {
data: response.data.conf.uiLayout.bottom
};
}

await setProxy();

/// #if BROWSER
await registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
/// #endif
addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript");
addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript");

setNoteBook();
initBlockPopover(this);

await loadPlugins(this);
getLocalStorage(() => {
fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => {
Expand All @@ -177,8 +185,6 @@ export class App {
});
});
});
setNoteBook();
initBlockPopover(this);
}
}

Expand Down
15 changes: 10 additions & 5 deletions app/src/mobile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,8 @@ class App {
public appId: string;

constructor() {
if (!window.webkit?.messageHandlers && !window.JSAndroid) {
registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
}
addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript");
addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript");
addBaseURL();

this.appId = Constants.SIYUAN_APPID;
window.siyuan = {
zIndex: 10,
Expand All @@ -60,6 +56,7 @@ class App {
}
})
};

// 不能使用 touchstart,否则会被 event.stopImmediatePropagation() 阻塞
window.addEventListener("click", (event: MouseEvent & { target: HTMLElement }) => {
if (!window.siyuan.menus.menu.element.contains(event.target) && !hasClosestByAttribute(event.target, "data-menu", "true")) {
Expand All @@ -80,9 +77,17 @@ class App {
window.addEventListener("pagehide", () => {
saveScroll(window.siyuan.mobile.editor.protyle);
}, false);

fetchPost("/api/system/getConf", {}, async (confResponse) => {
confResponse.data.conf.keymap = Constants.SIYUAN_KEYMAP;
window.siyuan.config = confResponse.data.conf;

if (!window.webkit?.messageHandlers && !window.JSAndroid) {
await registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
}
addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript");
addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript");

await loadPlugins(this);
getLocalStorage(() => {
fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => {
Expand Down
29 changes: 15 additions & 14 deletions app/src/util/serviceWorker.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
// https://github.com/siyuan-note/siyuan/pull/8012
export const registerServiceWorker = (scriptURL: string, scope = "/", workerType: WorkerType = "module") => {
if (!("serviceWorker" in navigator) || typeof (navigator.serviceWorker) === "undefined" ||
!("caches" in window) || !("fetch" in window)) {
return;
export const registerServiceWorker = async (scriptURL: string, scope = "/", workerType: WorkerType = "module") => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

和 proxy 没有关系的代码麻烦不要提交。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

和 proxy 没有关系的代码麻烦不要提交。

这里是为了避免加载 service-worker 时对现有请求造成不可预期的影响,是相关的

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个只有在浏览器端和移动端使用,和 electron 的 setProxy 无关。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个只有在浏览器端和移动端使用,和 electron 的 setProxy 无关。

我在使用中发现在 electron 中使用 <iframe><webview> 标签访问 /stage/build/desktop//stage/build/mobile/ 也会触发 service-worker

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registerServiceWorker 这个好像还是你 PR 的,是不是这些情况排查漏了。这个问题应该从源头上改进,而不是对错误进行兼容。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

registerServiceWorker 这个好像还是你 PR 的,是不是这些情况排查漏了。这个问题应该从源头上改进,而不是对错误进行兼容。

原有实现暂时也未出现问题, 这里的改进是为了消除不确定性

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前的 registerServiceWorker 为什么要在 electron 中运行?感觉是没有必要的。不是出现问题才是有 bug。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不是 registerServiceWorker 要在 electron 中运行, 而是无法完全阻止 registerServiceWorker 在 electron 中运行, 因为 <iframe><webview> 的上下文可能是完全隔离的

不过我刚刚有一个想法, 在 electron 环境中检测到 service-worker 后可以自动注销该 worker, 我先去测试一下

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Vanessa219
提交了一个解决方案: 在启动时从桌面端与移动端 App 中注销当前存在的 service-worker

详情请参考 36bad6c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

能不能不要搅和在这个 issue 里面呀 😭

if (("serviceWorker" in window.navigator) && ("caches" in window) && ("fetch" in window)) {
try {
// REF https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
const registration = await window.navigator.serviceWorker.register(scriptURL, {
scope,
type: workerType,
});
await registration.update();
return true;
} catch (error) {
console.debug(`Registration failed with ${error}`);
return false;
}
}
// REF https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
window.navigator.serviceWorker
.register(scriptURL, {
scope,
type: workerType,
}).then(registration => {
registration.update();
}).catch(e => {
console.debug(`Registration failed with ${e}`);
});
return false;
};