サービスワーカーを使用して私の要求を傍受し、同じ親ページから作成されたWebワーカーと通信して、フェッチ要求に対する応答を提供しています。 私は、ワーカーとサービスワーカーの間の直接通信にメッセージチャネルを使用しました。サービスワーカーが他のワーカーからデータを取得した後に取得する
var otherPort, parentPort;
var dummyObj;
var DummyHandler = function()
{
this.onmessage = null;
var selfRef = this;
this.callHandler = function(arg)
{
if (typeof selfRef.onmessage === "function")
{
selfRef.onmessage(arg);
}
else
{
console.error("Message Handler not set");
}
};
};
function msgFromW(evt)
{
console.log(evt.data);
dummyObj.callHandler(evt);
}
self.addEventListener("message", function(evt) {
var data = evt.data;
if(data.msg === "connect")
{
otherPort = evt.ports[1];
otherPort.onmessage = msgFromW;
parentPort = evt.ports[0];
parentPort.postMessage({"msg": "connect"});
}
});
self.addEventListener("fetch", function(event)
{
var url = event.request.url;
var urlObj = new URL(url);
if(!isToBeIntercepted(url))
{
return fetch(event.request);
}
url = decodeURI(url);
var key = processURL(url).toLowerCase();
console.log("Fetch For: " + key);
event.respondWith(new Promise(function(resolve, reject){
dummyObj = new DummyHandler();
dummyObj.onmessage = function(e)
{
if(e.data.error)
{
reject(e.data.error);
}
else
{
var content = e.data.data;
var blob = new Blob([content]);
resolve(new Response(blob));
}
};
otherPort.postMessage({"msg": "content", param: key});
}));
});
ポートの
役割:
otherPort:労働者とのコミュニケーション
parentPort:親ページとのコミュニケーション
でここで私が書いた簡単なPOCであります労働者、私はデータベースがこれを言う:
var dataBase = {
"file1.txt": "This is File1",
"file2.txt": "This is File2"
};
ワーカーは、サービスワーカーから送信されたキーに従って正しいデータを処理します。実際には、これらは非常に大きなファイルになります。
私はこれに直面しています問題は以下の通りです:
- 私はグローバルdummyObj、古いdummyObjを使用していますので、それ以上の年齢のonMessageが失われ、唯一、最新のリソースが受信したデータに対応しているので、 。
- 実際にfile2は
This is File1
になります。最新のdummyObjはfile2.txtですが、ワーカーはまずfile1.txtのデータを送信するためです。
私は直接のiframeを作成し、その中のすべての要求が傍受されていることで試してみました。ここで
<html>
<head></head>
<body><iframe src="tointercept/file1.txt" ></iframe><iframe src="tointercept/file2.txt"></iframe>
</body>
</html>
一つのアプローチは、すべて書くことができiframeを作成する前にWorkerのIndexedDBにフェッチできるファイルその後、Service Workerでインデックス付きDBからそれらをフェッチします。しかし私はIDBのすべてのリソースを節約したくありません。だから、このアプローチは私が望むものではありません。
誰かが私が何か他の方法でやろうとしていることを達成する方法を知っていますか?それとも私がやっていることに修正がありますか?
助けてください!
UPDATE
私は、グローバルキューにdummyObjsキューイングの代わりに、グローバルオブジェクトを持つことで動作するようにこれを持っています。 msgFromW
のワーカーからの応答を受け取ると、キューから要素がポップアップされ、callHandler
関数が呼び出されます。 しかし、これが信頼できる解決策であるかどうかはわかりません。それはすべてが順番に起こると仮定しているからです。 この仮定は正しいですか?
:
あなたが
promise-worker
を使用していた場合、あなたのコードは次のようになりますか? – tapananandあなたは約束を使用していますが、メッセージコールバックの外部で管理されているグローバルキューは必要ありません。特定のコールバックに限定された約束に頼ることができます。 –
私は約束を使用していますが、私は労働者からの応答を受け取ってダミーブブのonmessageを手動で呼び出します。だから私はキュー/マップがonmessageを呼び出すのを追跡する必要があります – tapananand