Skip to content

Commit 6ff24e3

Browse files
committed
🐛 修复vscode连接问题 #412 #400
close 在之前为了快速上线mv3到chrome商店未实现此功能
1 parent b8735d8 commit 6ff24e3

7 files changed

Lines changed: 174 additions & 6 deletions

File tree

src/app/service/offscreen/client.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { WindowMessage } from "@Packages/message/window_message";
22
import { SCRIPT_RUN_STATUS, ScriptRunResouce } from "@App/app/repo/scripts";
3-
import { sendMessage } from "@Packages/message/client";
3+
import { Client, sendMessage } from "@Packages/message/client";
44
import { MessageSend } from "@Packages/message/server";
5+
import { VSCodeConnect } from "./vscode-connect";
56

67
export function preparationSandbox(msg: WindowMessage) {
78
return sendMessage(msg, "offscreen/preparationSandbox");
@@ -35,3 +36,21 @@ export function stopScript(msg: MessageSend, uuid: string) {
3536
export function createObjectURL(msg: MessageSend, data: Blob) {
3637
return sendMessage(msg, "offscreen/createObjectURL", data);
3738
}
39+
40+
export class VscodeConnectClient extends Client {
41+
constructor(msg: MessageSend) {
42+
super(msg, "offscreen/vscodeConnect");
43+
}
44+
45+
connect(params: Parameters<VSCodeConnect["connect"]>[0]): ReturnType<VSCodeConnect["connect"]> {
46+
return this.do("connect", params);
47+
}
48+
49+
changeReConnect(params: Parameters<VSCodeConnect["changeReConnect"]>[0]): ReturnType<VSCodeConnect["changeReConnect"]> {
50+
return this.do("changeReConnect", params);
51+
}
52+
53+
disconnect(): ReturnType<VSCodeConnect["disconnect"]> {
54+
return this.do("disconnect");
55+
}
56+
}

src/app/service/offscreen/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ServiceWorkerClient } from "../service_worker/client";
77
import { sendMessage } from "@Packages/message/client";
88
import GMApi from "./gm_api";
99
import { MessageQueue } from "@Packages/message/message_queue";
10+
import { VSCodeConnect } from "./vscode-connect";
1011

1112
// offscreen环境的管理器
1213
export class OffscreenManager {
@@ -54,9 +55,10 @@ export class OffscreenManager {
5455

5556
const gmApi = new GMApi(this.windowServer.group("gmApi"));
5657
gmApi.init();
58+
const vscodeConnect = new VSCodeConnect(this.windowServer.group("vscodeConnect"));
59+
vscodeConnect.init();
5760

5861
this.windowServer.on("createObjectURL", (data: Blob) => {
59-
console.log("createObjectURL", data);
6062
const url = URL.createObjectURL(data);
6163
setTimeout(() => {
6264
URL.revokeObjectURL(url);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import LoggerCore from "@App/app/logger/core";
2+
import Logger from "@App/app/logger/logger";
3+
import { prepareScriptByCode } from "@App/pkg/utils/script";
4+
import { Group } from "@Packages/message/server";
5+
6+
// 在offscreen下与scriptcat-vscode建立websocket连接
7+
// 需要在vscode中安装scriptcat-vscode插件
8+
export class VSCodeConnect {
9+
logger: Logger = LoggerCore.logger().with({ service: "VSCodeConnect" });
10+
11+
reconnect: boolean = false;
12+
13+
wsConnect: WebSocket | undefined;
14+
15+
connectVSCodeTimer: any;
16+
17+
constructor(private group: Group) {}
18+
19+
connect({ url, reconnect }: { url: string; reconnect: boolean }) {
20+
// 如果已经连接,断开重连
21+
if (this.wsConnect) {
22+
this.wsConnect.close();
23+
}
24+
// 清理老的定时器
25+
if (this.connectVSCodeTimer) {
26+
clearInterval(this.connectVSCodeTimer);
27+
this.connectVSCodeTimer = undefined;
28+
}
29+
const handler = () => {
30+
if (!this.wsConnect) {
31+
return this.connectVSCode({ url });
32+
}
33+
return Promise.resolve();
34+
};
35+
if (reconnect) {
36+
this.connectVSCodeTimer = setInterval(() => {
37+
handler();
38+
}, 30 * 1000);
39+
}
40+
return handler();
41+
}
42+
43+
// 连接到vscode
44+
connectVSCode({ url }: { url: string }) {
45+
return new Promise<void>((resolve, reject) => {
46+
// 如果已经连接,断开重连
47+
if (this.wsConnect) {
48+
this.wsConnect.close();
49+
}
50+
try {
51+
this.wsConnect = new WebSocket(url);
52+
} catch (e: any) {
53+
this.logger.debug("connect vscode faild", Logger.E(e));
54+
return Promise.reject(e);
55+
}
56+
let ok = false;
57+
this.wsConnect.addEventListener("open", () => {
58+
this.wsConnect!.send('{"action":"hello"}');
59+
ok = true;
60+
resolve();
61+
});
62+
this.wsConnect.addEventListener("message", async (ev) => {
63+
const data = JSON.parse(ev.data);
64+
switch (data.action) {
65+
case "onchange": {
66+
// 调用安装脚本接口
67+
// const code = data.data.script;
68+
// const prepareScript = await prepareScriptByCode(code, "", uuidv5(data.data.uri, uuidv5.URL), true);
69+
// this.scriptManager.event.upsertHandler(prepareScript.script, "vscode");
70+
break;
71+
}
72+
default:
73+
}
74+
});
75+
76+
this.wsConnect.addEventListener("error", (e) => {
77+
this.wsConnect = undefined;
78+
this.logger.debug("connect vscode faild", Logger.E(e));
79+
if (!ok) {
80+
reject(new Error("connect fail"));
81+
}
82+
});
83+
84+
this.wsConnect.addEventListener("close", () => {
85+
this.wsConnect = undefined;
86+
this.logger.debug("vscode connection closed");
87+
});
88+
});
89+
}
90+
91+
init() {
92+
this.group.on("connect", this.connect.bind(this));
93+
}
94+
}

src/app/service/service_worker/client.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import CacheKey from "@App/app/cache_key";
1212
import { Subscribe } from "@App/app/repo/subscribe";
1313
import { Permission } from "@App/app/repo/permission";
1414
import { ResourceBackup } from "@App/pkg/backup/struct";
15+
import { VSCodeConnect } from "../offscreen/vscode-connect";
1516

1617
export class ServiceWorkerClient extends Client {
1718
constructor(msg: MessageSend) {
@@ -332,3 +333,13 @@ export class SubscribeClient extends Client {
332333
return this.do("enable", { url, enable });
333334
}
334335
}
336+
337+
export class SystemClient extends Client {
338+
constructor(msg: MessageSend) {
339+
super(msg, "serviceWorker/system");
340+
}
341+
342+
connectVSCode(params: Parameters<VSCodeConnect["connect"]>[0]): ReturnType<VSCodeConnect["connect"]> {
343+
return this.do("connectVSCode", params);
344+
}
345+
}

src/app/service/service_worker/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { SubscribeService } from "./subscribe";
1212
import { ExtServer, ExtVersion } from "@App/app/const";
1313
import { systemConfig } from "@App/pages/store/global";
1414
import { ScriptCodeDAO, ScriptDAO } from "@App/app/repo/scripts";
15+
import { SystemService } from "./system";
1516

1617
export type InstallSource = "user" | "system" | "sync" | "subscribe" | "vscode";
1718

@@ -67,6 +68,8 @@ export default class ServiceWorkerManager {
6768
synchronize.init();
6869
const subscribe = new SubscribeService(systemConfig, this.api.group("subscribe"), this.mq, script);
6970
subscribe.init();
71+
const system = new SystemService(systemConfig, this.api.group("system"), this.sender);
72+
system.init();
7073

7174
// 定时器处理
7275
chrome.alarms.onAlarm.addListener((alarm) => {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { SystemConfig } from "@App/pkg/config/config";
2+
import { Group, MessageSend } from "@Packages/message/server";
3+
import { VscodeConnectClient } from "../offscreen/client";
4+
import Cache from "@App/app/cache";
5+
6+
// 一些系统服务
7+
export class SystemService {
8+
constructor(
9+
private systemConfig: SystemConfig,
10+
private group: Group,
11+
private sender: MessageSend
12+
) {}
13+
14+
async init() {
15+
const vscodeConnect = new VscodeConnectClient(this.sender);
16+
// 如果开启了自动连接vscode,则自动连接
17+
// 使用tx来确保service_worker恢复时不会再执行
18+
Cache.getInstance().tx("vscodeReconnect", async (init) => {
19+
if (init) {
20+
if (await this.systemConfig.getVscodeReconnect()) {
21+
// 调用连接
22+
vscodeConnect.connect({
23+
url: await this.systemConfig.getVscodeUrl(),
24+
reconnect: true,
25+
});
26+
}
27+
}
28+
return true;
29+
});
30+
this.group.on("connectVSCode", (params) => {
31+
return vscodeConnect.connect(params);
32+
});
33+
}
34+
}

src/pages/options/routes/Tools.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import { RefInputType } from "@arco-design/web-react/es/Input/interface";
88
import { useTranslation } from "react-i18next";
99
import FileSystemFactory, { FileSystemType } from "@Packages/filesystem/factory";
1010
import { File, FileReader } from "@Packages/filesystem/filesystem";
11-
import { systemConfig } from "@App/pages/store/global";
11+
import { message, systemConfig } from "@App/pages/store/global";
1212
import { synchronizeClient } from "@App/pages/store/features/script";
13+
import { SystemConfig } from "@App/pkg/config/config";
14+
import { SystemClient } from "@App/app/service/service_worker/client";
1315

1416
function Tools() {
1517
const [loading, setLoading] = useState<{ [key: string]: boolean }>({});
@@ -310,9 +312,12 @@ function Tools() {
310312
onClick={() => {
311313
systemConfig.setVscodeUrl(vscodeUrl);
312314
systemConfig.setVscodeReconnect(vscodeReconnect);
313-
const ctrl = IoC.instance(SystemController) as SystemController;
314-
ctrl
315-
.connectVSCode()
315+
const systemClient = new SystemClient(message);
316+
systemClient
317+
.connectVSCode({
318+
url: vscodeUrl,
319+
reconnect: vscodeReconnect,
320+
})
316321
.then(() => {
317322
Message.success(t("connection_success")!);
318323
})

0 commit comments

Comments
 (0)