Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions src/offscreen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import LoggerCore from "./app/logger/core";
import MessageWriter from "./app/logger/message_writer";
import { OffscreenManager } from "./app/service/offscreen";
import { ServiceWorkerClientMessage } from "@Packages/message/window_message";
import { startRepetitivePing } from "./pkg/utils/wakeup-ping";

function main() {
// 通过postMessage与SW通信,支持结构化克隆(Blob等)
Expand All @@ -15,6 +16,7 @@ function main() {
// 初始化管理器
const manager = new OffscreenManager(swPostMessage);
manager.initManager();
startRepetitivePing();
}

main();
63 changes: 63 additions & 0 deletions src/pkg/utils/wakeup-ping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const PING_INTERVAL_MS_1 = 13_225;
const PING_INTERVAL_MS_2 = 17_765;

/**
* scheduler 用于后台排程:Chrome 94+, Firefox 142+
* @link https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask
*/
const nativeScheduler =
//@ts-ignore
typeof scheduler !== "undefined" && typeof scheduler?.postTask === "function" && scheduler;

// 高效的 BroadcastChannel 通讯:service worker 和 offscreen 共用同一通道
const channel = new BroadcastChannel("custom-ping");

export const startRepetitivePing = () => {
if (typeof frameElement === "object" && typeof document === "object" && document) {
let counter = 0;
let isMutationPending = false;

const pingNode = document.createComment("0");

const incrementCounter = () => {
if (!isMutationPending) {
isMutationPending = true;
counter = counter > 8 ? 1 : counter + 1;
pingNode.data = `${counter}`;
}
};

const pingTask = async () => {
channel.postMessage({});
incrementCounter();
};

const mutationObserver = new MutationObserver(() => {
if (isMutationPending) {
isMutationPending = false;
const pingIntervalMs = Math.random() * (PING_INTERVAL_MS_2 - PING_INTERVAL_MS_1) + PING_INTERVAL_MS_1;
if (nativeScheduler) {
nativeScheduler.postTask(pingTask, { priority: "background", delay: pingIntervalMs });
} else {
setTimeout(pingTask, pingIntervalMs);
}
}
});
mutationObserver.observe(pingNode, { characterData: true });
incrementCounter();
}
};

export const listenWakeupPing = (onWakeupPing: (...args: any) => any) => {
chrome.storage.session.onChanged.addListener((obj) => {
// 消耗 persistentWakeup
if (typeof obj.persistentWakeup !== "undefined") {
// 执行任意 callback
onWakeupPing();
}
});
channel.onmessage = (e) => {
// 触发 chrome storage onChanged 使 service worker 保持活跃
chrome.storage.session.set({ persistentWakeup: `${e.timeStamp}` });
};
};
6 changes: 6 additions & 0 deletions src/service_worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MessageQueue } from "@Packages/message/message_queue";
import { ServiceWorkerMessageSend } from "@Packages/message/window_message";
import migrate, { migrateChromeStorage } from "./app/migrate";
import { cleanInvalidKeys } from "./app/repo/resource";
import { listenWakeupPing } from "./pkg/utils/wakeup-ping";

migrate();
migrateChromeStorage();
Expand Down Expand Up @@ -59,6 +60,10 @@ async function setupOffscreenDocument() {
}
}

export const onWakeupPing = () => {
console.debug("onWakeupPing"); // 不用记录在系统日志
};

function main() {
cleanInvalidKeys();
// 初始化管理器
Expand All @@ -77,6 +82,7 @@ function main() {
manager.initManager();
// 初始化沙盒环境
setupOffscreenDocument();
listenWakeupPing(onWakeupPing);
}

main();
Loading