跨頁面通訊
cross tabs communication
1. Broadcast Channel API
code:javascript
const bc = new BroadcastChannel("a_channel");
// listen to message
bc.onmessage = function (e) {
const data = e.data;
const text = [receive] ${data.msg} --- ${data.from};
console.log("BroadcastChannel receive message", text);
};
// send message
bc.postMessage(data);
2. Service Worker
code:javascript
navigator.serviceWorker.register("../util.sw.js").then(function () {
console.log("Service Worker registered");
});
navigator.serviceWorker.addEventListener("message", function (e) {
const data = e.data;
const text = [receive] ${data.msg} --- ${data.from};
console.log("ServiceWorker receive message", text);
});
navigator.serviceWorker.controller.postMessage(data);
// ../util.sw.js
self.addEventListener("message", function (e) {
console.log("Service Worker receive message", e.data);
e.wailUntil(
self.clients.matchAll().then(function (clients) {
if (!clients || clients.length === 0) {
return;
}
clients.forEach(function (client) {
client.postMessage(e.data);
});
})
);
});
3. LocalStorage
code:javascript
window.addEventListener("storage", function (e) {
if (e.key === "ctc-msg") {
const data = JSON.parse(e.newValue);
const text = [receive] ${data.msg} --- ${data.from};
console.log("LocalStorage receive message", text);
}
});
data.st = +new Date();
window.localStorage.setItem("ctc-msg", JSON.stringify(data));
4. SharedWorker
code:javascript
const sharedWorker = new SharedWorker("../util.shared.js", "ctc");
setInterval(function () {
sharedWorker.port.postMessage({ get: true });
}, 1000);
sharedWorker.port.addEventListener(
"message",
(e) => {
const data = e.data;
const text = [receive] ${data.msg} --- ${data.from};
console.log("SharedWorker receive message", text);
},
false
);
sharedWorker.port.start();
sharedWorker.port.postMessage(data);
// ../util.shared.js
let data = null;
self.addEventListener("connect", function (e) {
const port = e.ports0;
port.addEventListener("message", function (event) {
if (event.data.get) {
data && port.postMessage(data);
} else {
data = event.data;
}
});
port.start();
});
5. IndexedDB
code:javascript
function openStore() {
const storeName = "ctc_aleinzhou";
return new Promise(function (resolve, reject) {
if (!("indexedDB" in window)) {
return reject("don't support indexedDB");
}
const request = indexedDB.open("CTC_DB", 1);
request.onerror = reject;
request.onsuccess = (e) => resolve(e.target.result);
request.onupgradeneeded = function (e) {
const db = e.srcElement.result;
if (e.oldVersion === 0 && !db.objectStoreNames.contains(storeName)) {
const store = db.createObjectStore(storeName, { keyPath: "tag" });
store.createIndex(storeName + "Index", "tag", { unique: false });
}
};
});
}
function saveData(db, data) {
return new Promise(function (resolve, reject) {
const STORE_NAME = "ctc_aleinzhou";
const tx = db.transaction(STORE_NAME, "readwrite");
const store = tx.objectStore(STORE_NAME);
const request = store.put({ tag: "ctc_data", data });
request.onsuccess = () => resolve(db);
request.onerror = reject;
});
}
function query(db) {
const STORE_NAME = "ctc_aleinzhou";
return new Promise(function (resolve, reject) {
try {
const tx = db.transaction(STORE_NAME, "readonly");
const store = tx.objectStore(STORE_NAME);
const dbRequest = store.get("ctc_data");
dbRequest.onsuccess = (e) => resolve(e.target.result);
dbRequest.onerror = reject;
} catch (err) {
reject(err);
}
});
}
openStore().then((db) => saveData(db, null));
openStore()
.then((db) => saveData(db, null))
.then(function (db) {
setInterval(function () {
query(db).then(function (res) {
if (!res || !res.data) {
return;
}
const data = res.data;
const text = "receive " + data.msg + " —— tab " + data.from;
console.log("Storage I receive message:", text);
});
}, 1000);
});
openStore()
.then((db) => saveData(db, null))
.then(function (db) {
saveData(db, mydata);
});
2023-12-07 リアルタイム通信用のコネクションをタブ間で共有してまとめる
SharedWorker