Skip to content

在其他页面中使用消息管理

typescript
//  background.ts
import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

//  注意⚠️这里引用的文件位置为 @webextkits/messages-center/background
import { MessageInstance } from "@webextkits/messages-center/background";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  //  为了不与其他扩展的消息冲突,这里需要传入唯一表示符,也就是你扩展的别名
  extId,
  //  是否开启 debug,默认是关闭,传入 true 后将会在接收到消息和返回消息时候打印信息到控制台
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}
//  background.ts
import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

//  注意⚠️这里引用的文件位置为 @webextkits/messages-center/background
import { MessageInstance } from "@webextkits/messages-center/background";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  //  为了不与其他扩展的消息冲突,这里需要传入唯一表示符,也就是你扩展的别名
  extId,
  //  是否开启 debug,默认是关闭,传入 true 后将会在接收到消息和返回消息时候打印信息到控制台
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}

在 options 页面监听消息

只要是能执行 runtime.onMessageExternal.addListener 的页面,你都可以通过上面这种方式监听 injectScript 传递过来的消息,比如在 optionspopup 页面

typescript
// options/app.tsx

import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  extId,
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}
// options/app.tsx

import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  extId,
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}

注意

如果你在多个地方对同一个消息进行了监听处理,那么只有一个监听函数会执行,这个是 chrome 的政策

If multiple pages are listening for onMessage events, only the first to call sendResponse() for a particular event will succeed in sending the response. All other responses to that event will be ignored.

如何获取 tabId

在监听到事件之后,我们可能要知道 sender 到底是谁,获取对应的 tabId 进行操作。我们可以通过 this 指向来获取 sender 的数据

typescript
mc.on("setUserName", function (name: string) {
  //  在此处获取 this.sender
  console.log(this.sender);

  //  从 sender 中获取 tabId(如需仅给当前来源页发送消息)
  const tabId = this.sender?.tab?.id;
  if (tabId) {
    //  使用 sendByTabId 仅向当前来源页面发送确认/反馈消息
    mc.sendByTabId(tabId, "setUserNameAck", name);
  }
});
mc.on("setUserName", function (name: string) {
  //  在此处获取 this.sender
  console.log(this.sender);

  //  从 sender 中获取 tabId(如需仅给当前来源页发送消息)
  const tabId = this.sender?.tab?.id;
  if (tabId) {
    //  使用 sendByTabId 仅向当前来源页面发送确认/反馈消息
    mc.sendByTabId(tabId, "setUserNameAck", name);
  }
});

按指定 tabId 发送消息

当你只想向某一个特定页面发送消息时,可以使用 sendByTabId(tabId, action, ...payload)

typescript
// 已知 tabId 时,直接向该页面发送
await mc.sendByTabId(123, "readUserName");
// 已知 tabId 时,直接向该页面发送
await mc.sendByTabId(123, "readUserName");

你也可以接收页面返回的结果

typescript
// 已知 tabId 时,直接向该页面发送
mc.sendByTabId(123, "readUserName").then(console.log);
// 已知 tabId 时,直接向该页面发送
mc.sendByTabId(123, "readUserName").then(console.log);

向所有已连接页面广播

如果你希望向所有已建立连接(connect)的页面发送同一条消息,使用 send(action, ...payload)

typescript
await mc.send("readUserName");
await mc.send("readUserName");

向所有已链接的页面广播并且处理返回结果

每个页面返回的结果都会调用第二个 callback 方法,并且接受 result: 返回结果 sender: 这个 tab 的信息

typescript
mc.sendWithCallback(
  "eventName",
  (result, sender) => {
    console.log(result, sender);
  },
  args
);
mc.sendWithCallback(
  "eventName",
  (result, sender) => {
    console.log(result, sender);
  },
  args
);

Powered by Vitepress