From 36cf8ef5a7d30f2e629de5f4d130a035a0d6ab56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Mon, 10 Feb 2025 18:10:50 +0800 Subject: [PATCH] 0210 --- packages/message/client.ts | 1 - packages/message/extension_message.ts | 17 ++++++++++--- packages/message/message_queue.ts | 2 ++ packages/message/server.ts | 21 +++++----------- packages/message/window_message.ts | 6 +++++ src/app/service/offscreen/gm_api.ts | 6 ++++- src/app/service/offscreen/index.ts | 13 ++++------ src/app/service/sandbox/index.ts | 2 +- src/app/service/service_worker/gm_api.ts | 30 ++++++++++++++++++++++- src/app/service/service_worker/index.ts | 6 ++--- src/app/service/service_worker/runtime.ts | 2 +- 11 files changed, 71 insertions(+), 35 deletions(-) diff --git a/packages/message/client.ts b/packages/message/client.ts index 0118aac..8540a73 100644 --- a/packages/message/client.ts +++ b/packages/message/client.ts @@ -1,6 +1,5 @@ import LoggerCore from "@App/app/logger/core"; import { Message, MessageConnect, MessageSend } from "./server"; -import { ExtensionMessageSend } from "./extension_message"; export async function sendMessage(msg: MessageSend, action: string, data?: any): Promise { const res = await msg.sendMessage({ action, data }); diff --git a/packages/message/extension_message.ts b/packages/message/extension_message.ts index 610b062..1ca523d 100644 --- a/packages/message/extension_message.ts +++ b/packages/message/extension_message.ts @@ -1,14 +1,16 @@ import { Message, MessageConnect, MessageSend } from "./server"; export class ExtensionMessageSend implements MessageSend { - constructor(private serverEnv: string) { - // 由于service_worker和offscren同时监听消息的话,都会同时收到,用serverEnv于区分不同的环墨 - } + constructor(protected serverEnv: string) {} connect(data: any): Promise { return new Promise((resolve) => { const con = chrome.runtime.connect(); - con.postMessage(data); + con.postMessage( + Object.assign(data, { + serverEnv: this.serverEnv, + }) + ); resolve(new ExtensionMessageConnect(con)); }); } @@ -33,6 +35,10 @@ export class ExtensionMessage extends ExtensionMessageSend implements Message { chrome.runtime.onConnect.addListener((port) => { const handler = (msg: any) => { port.onMessage.removeListener(handler); + if (msg.serverEnv !== this.serverEnv) { + port.disconnect(); + return false; + } callback(msg, new ExtensionMessageConnect(port)); }; port.onMessage.addListener(handler); @@ -42,6 +48,9 @@ export class ExtensionMessage extends ExtensionMessageSend implements Message { // 注意chrome.runtime.onMessage.addListener的回调函数需要返回true才能处理异步请求 onMessage(callback: (data: any, sendResponse: (data: any) => void) => void) { chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { + if (msg.serverEnv !== this.serverEnv) { + return false; + } return callback(msg, sendResponse); }); } diff --git a/packages/message/message_queue.ts b/packages/message/message_queue.ts index ed110a0..95bdfba 100644 --- a/packages/message/message_queue.ts +++ b/packages/message/message_queue.ts @@ -11,8 +11,10 @@ export class Broker { // 订阅 async subscribe(topic: string, handler: SubscribeCallback): Promise { + LoggerCore.getInstance().logger({ service: "messageQueue" }).debug("subscribe", { topic }); const con = await this.msg.connect({ action: "messageQueue", data: { action: "subscribe", topic } }); con.onMessage((msg: { action: string; topic: string; message: any }) => { + console.log(msg); if (msg.action === "message") { handler(msg.message); } diff --git a/packages/message/server.ts b/packages/message/server.ts index a0060dd..29d8ddf 100644 --- a/packages/message/server.ts +++ b/packages/message/server.ts @@ -1,5 +1,4 @@ import LoggerCore from "@App/app/logger/core"; -import { ExtensionMessageSend } from "./extension_message"; export interface Message extends MessageSend { onConnect(callback: (data: any, con: MessageConnect) => void): void; @@ -27,22 +26,16 @@ export type ApiFunction = (params: any, con: MessageConnect | null) => Promise = new Map(); - constructor( - private env: string, - message: Message - ) { + private logger = LoggerCore.getInstance().logger({ service: "messageServer" }); + + constructor(message: Message) { message.onConnect((msg: any, con: MessageConnect) => { - if (msg.serverEnv !== this.env) { - con.disconnect(); - return; - } + this.logger.trace("server onConnect", { msg }); this.connectHandle(msg.action, msg.data, con); }); message.onMessage((msg, sendResponse) => { - if (msg.serverEnv !== this.env) { - return; - } + this.logger.trace("server onMessage", { msg }); return this.messageHandle(msg.action, msg.data, sendResponse); }); } @@ -63,8 +56,6 @@ export class Server { } private messageHandle(msg: string, params: any, sendResponse: (response: any) => void) { - const logger = LoggerCore.getInstance().logger({ env: this.env, msg }); - logger.trace("messageHandle", { params }); const func = this.apiFunctionMap.get(msg); if (func) { try { @@ -82,7 +73,7 @@ export class Server { } } else { sendResponse({ code: -1, message: "no such api" }); - logger.error("no such api"); + this.logger.error("no such api", { msg }); } } } diff --git a/packages/message/window_message.ts b/packages/message/window_message.ts index 85b16eb..efa58cc 100644 --- a/packages/message/window_message.ts +++ b/packages/message/window_message.ts @@ -23,6 +23,7 @@ export class WindowMessage implements Message { ) { // 监听消息 this.source.addEventListener("message", (e) => { + console.log(e); if (e.source === this.target || e.source === this.source) { this.messageHandle(e.data); } @@ -35,6 +36,11 @@ export class WindowMessage implements Message { // 接收到消息 this.EE.emit("message", data.data, (resp: any) => { // 发送响应消息 + // 无消息id则不发送响应消息 + console.log("data", data, "resp", resp); + if (!data.messageId) { + return; + } const body: WindowMessageBody = { messageId: data.messageId, type: "respMessage", diff --git a/src/app/service/offscreen/gm_api.ts b/src/app/service/offscreen/gm_api.ts index 1b7fa71..41cf4e7 100644 --- a/src/app/service/offscreen/gm_api.ts +++ b/src/app/service/offscreen/gm_api.ts @@ -3,5 +3,9 @@ import { Group } from "@Packages/message/server"; export class GMApi { constructor(private group: Group) {} - init() {} + init() { + this.group.on("requestXhr", async (data) => { + console.log(data); + }); + } } diff --git a/src/app/service/offscreen/index.ts b/src/app/service/offscreen/index.ts index add2d4d..b7be4ce 100644 --- a/src/app/service/offscreen/index.ts +++ b/src/app/service/offscreen/index.ts @@ -1,22 +1,20 @@ -import { forwardMessage, Message, Server } from "@Packages/message/server"; +import { forwardMessage, MessageSend, Server } from "@Packages/message/server"; import { ScriptService } from "./script"; import { Broker } from "@Packages/message/message_queue"; import { Logger, LoggerDAO } from "@App/app/repo/logger"; import { WindowMessage } from "@Packages/message/window_message"; -import { ExtensionMessage } from "@Packages/message/extension_message"; +import { ExtensionMessageSend } from "@Packages/message/extension_message"; import { ServiceWorkerClient } from "../service_worker/client"; import { sendMessage } from "@Packages/message/client"; import { GMApi } from "./gm_api"; // offscreen环境的管理器 export class OffscreenManager { - private extensionMessage: Message = new ExtensionMessage("service_worker"); - - private api: Server = new Server("offscreen", this.extensionMessage); + private extensionMessage: MessageSend = new ExtensionMessageSend("service_worker"); private windowMessage = new WindowMessage(window, sandbox); - private windowApi: Server = new Server("offscreen-window", this.windowMessage); + private windowApi: Server = new Server(this.windowMessage); private broker: Broker = new Broker(this.extensionMessage); @@ -45,8 +43,7 @@ export class OffscreenManager { script.init(); // 转发gm api请求 forwardMessage("serviceWorker/runtime/gmApi", this.windowApi, this.extensionMessage); - // 处理gm请求 - const gmApi = new GMApi(this.api.group("gmApi")); + const gmApi = new GMApi(this.windowApi.group("gmApi")); gmApi.init(); // // 处理gm xhr请求 diff --git a/src/app/service/sandbox/index.ts b/src/app/service/sandbox/index.ts index 293df48..fe858d6 100644 --- a/src/app/service/sandbox/index.ts +++ b/src/app/service/sandbox/index.ts @@ -5,7 +5,7 @@ import { Runtime } from "./runtime"; // sandbox环境的管理器 export class SandboxManager { - api: Server = new Server("sandbox", this.windowMessage); + api: Server = new Server(this.windowMessage); constructor(private windowMessage: WindowMessage) {} diff --git a/src/app/service/service_worker/gm_api.ts b/src/app/service/service_worker/gm_api.ts index 925cfbb..80ed9bd 100644 --- a/src/app/service/service_worker/gm_api.ts +++ b/src/app/service/service_worker/gm_api.ts @@ -76,12 +76,40 @@ export default class GMApi { @PermissionVerify.API() GM_xmlhttpRequest(request: Request, con: MessageConnect) { - console.log("xml", request, con); + console.log("xml request", request, con); // 先处理unsafe hearder // 再发送到offscreen, 处理请求 + sendMessageToOffsreen("offscreen/gmApi/requestXhr", request.params); } start() { this.group.on("gmApi", this.handlerRequest.bind(this)); } } + +export async function sendMessageToOffsreen(action: string, data?: any) { + // service_worker通过chrome.scripting.executeScript调用window.postMessage主动发送消息 + // service_worker和offscreen同时监听消息,会导致消息被两边同时接收,但是返回结果时会产生问题,导致报错 + // 不进行监听的话又无法从service_worker主动发送消息 + const ctx = await chrome.runtime.getContexts({ + contextTypes: [chrome.runtime.ContextType.OFFSCREEN_DOCUMENT], + documentUrls: [chrome.runtime.getURL("src/offscreen.html")], + }); + chrome.scripting.executeScript({ + target: { + documentIds: [ctx[0]!.documentId!], + tabId: -1, + }, + func: (message) => { + // 在页面上下文中执行的代码 + window.postMessage( + { + type: "sendMessage", + daat: message, + }, + "*" + ); + }, + args: [{ action, data }], + }); +} diff --git a/src/app/service/service_worker/index.ts b/src/app/service/service_worker/index.ts index 411ffa8..e5a1587 100644 --- a/src/app/service/service_worker/index.ts +++ b/src/app/service/service_worker/index.ts @@ -12,13 +12,13 @@ export type InstallSource = "user" | "system" | "sync" | "subscribe" | "vscode"; export default class ServiceWorkerManager { constructor() {} - private api: Server = new Server("service_worker", new ExtensionMessage("service_worker")); + private api: Server = new Server(new ExtensionMessage("service_worker")); private mq: MessageQueue = new MessageQueue(this.api); - initManager() { + async initManager() { const group = this.api.group("serviceWorker"); - group.on("preparationOffscreen", () => { + group.on("preparationOffscreen", async () => { // 准备好环境 this.mq.emit("preparationOffscreen", {}); }); diff --git a/src/app/service/service_worker/runtime.ts b/src/app/service/service_worker/runtime.ts index 6a2bba5..60350d7 100644 --- a/src/app/service/service_worker/runtime.ts +++ b/src/app/service/service_worker/runtime.ts @@ -2,8 +2,8 @@ import { MessageQueue } from "@Packages/message/message_queue"; import { ScriptEnableCallbackValue } from "./client"; import { Group } from "@Packages/message/server"; import { Script, SCRIPT_STATUS_ENABLE, SCRIPT_TYPE_NORMAL, ScriptAndCode, ScriptDAO } from "@App/app/repo/scripts"; -import GMApi from "@App/runtime/service_worker/gm_api"; import { ValueService } from "./value"; +import GMApi from "./gm_api"; export class RuntimeService { scriptDAO: ScriptDAO = new ScriptDAO();