如图:
那么通信机制为什么要存在?那是因为有时候我们的逻辑可能会写在background中,假设你有一个popup的界面,在background中的处理逻辑,可以将处理结果发送给popup。或者在popup中需要往content_script发送一些数据,这个时候你依然要依赖background的来转发,这些在不同运行环境内的脚本,有一定的场景需要使用到通信,了解到这个通信机制之后,其实它是一个非常简单的事情,基本上我们只需要了解其中的两种模式即可:
问答模式
我们可以想象一下一个请求的全部生命周期,从request开始到response结束,在这个模式中也是如此。
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// request 问的人发过来的消息
// sendResponse 将答发给问的人
})
// 问的人
chrome.runtime.sendMessage({}, (response) => {
// 处理
})
一般这种问答机制我们还需要额外加入一些处理过程,如:
{
"action": "",
"args": "",
"id": ""
}
action用于描述处理的handler,args是问的人发来的消息,id属于幂等操作,定义这样的数据过程,在整个问答模式中,才能处理的很平稳。
long connect 模式
如果你了解过WebSocket那么对于这样的模式就会比较清楚,这个模式非常形象的和Websocket类似,它可以将消息体源源不断的发送给连接发起方。在long connect模式中,主要分为连接发起方和被动连接方,一般正常情况下,这个模式的被动连接方会写在background中,连接发起方可以写在popup中也可以写在content_script或options中,这样主要会根据你的业务逻辑而定。
// 被动连接方
chrome.runtime.onConnect.addListener((port) => {
switch (port.name) {
case COMM.FETCH_PIPE:
break;
default:
break;
}
});
// 连接发起方
let PORT = null;
PORT = chrome.runtime.connect({ name: COMM.FETCH_PIPE });
PORT.postMessage({ cmd: 'connect_pipe' });
PORT.onDisconnect.addListener(() => { console.log('disconnect');
});
PORT.onMessage.addListener(() => {
const data = Object.create(null);
data[COMM.LOCAL_TABLE] = tempExtensionResponse;
storageSet(data).then(() => {
window.location.reload();
});
});
跟上一个模式类似,如果我们要在业务中平稳的使用,还需要自己定义一些数据结构来辅助的处理通信的Handler逻辑。