Signatur
Beschreibung
Das Ereignis connect ist der Einstiegspunkt jedes Shared Workers. Erzeugt ein Dokument mit derselben Herkunft (Origin) per new SharedWorker(url, name) eine Verbindung zu einem bereits laufenden oder neu gestarteten Worker, löst der Browser im globalen Gültigkeitsbereich des Workers (SharedWorkerGlobalScope) ein connect-Ereignis aus. Das Ereignisobjekt ist ein MessageEvent.
Wichtig ist event.ports[0] (identisch mit event.source): ein MessagePort, über den der Worker mit genau diesem Client kommuniziert. Den Port merkt man sich z. B. in einem Array oder Set. So lassen sich Nachrichten an alle verbundenen Tabs verteilen, etwa bei einer gemeinsam genutzten WebSocket-Verbindung, einem zentralen Cache oder für die Abstimmung zwischen Tabs.
Einen Handler kann man mit self.addEventListener("connect", handler) oder über die Eigenschaft self.onconnect = handler registrieren. Das Ereignis wird nicht weitergereicht (bubbles nicht) und lässt sich nicht abbrechen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "connect". |
|
| $handler Pflicht | (event: MessageEvent) => void | Callback-Funktion. Sie bekommt ein MessageEvent, dessen ports[0] der MessagePort des neuen Clients ist. data ist ein leerer String, origin und lastEventId sind ebenfalls leer. |
|
| $options | boolean | AddEventListenerOptions | false | Die üblichen Optionen von addEventListener (once, signal …). |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein MessageEvent.Beispiele
Grundgerüst: Client verbindet sich, Worker antwortet
// worker.js (Shared Worker)
self.addEventListener("connect", (event) => {
const port = event.ports[0];
port.addEventListener("message", (e) => {
port.postMessage(`Echo: ${e.data}`);
});
port.start(); // nötig, wenn addEventListener statt onmessage genutzt wird
});
// main.js (Seite)
const worker = new SharedWorker("worker.js");
worker.port.onmessage = (e) => console.log(e.data);
worker.port.postMessage("Hallo");
Broadcast an alle offenen Tabs mit onconnect
// broadcast-worker.js
const ports = new Set();
self.onconnect = (event) => {
const port = event.ports[0];
ports.add(port);
// onmessage startet den Port automatisch
port.onmessage = ({ data }) => {
if (data === "bye") {
ports.delete(port);
return;
}
for (const p of ports) p.postMessage({ from: "worker", data, clients: ports.size });
};
port.postMessage({ from: "worker", data: "verbunden", clients: ports.size });
};
// in jedem Tab
const sw = new SharedWorker("broadcast-worker.js", { name: "broadcast" });
sw.port.onmessage = ({ data }) => console.log(data);
sw.port.postMessage("Neuer Stand gespeichert");
window.addEventListener("pagehide", () => sw.port.postMessage("bye"));
Handler mit AbortController wieder entfernen
// worker.js
const controller = new AbortController();
let count = 0;
self.addEventListener("connect", (event) => {
count += 1;
const port = event.ports[0];
if (count > 3) {
port.postMessage("Zu viele Clients");
port.close();
controller.abort(); // Listener abmelden, weitere Clients werden ignoriert
return;
}
port.postMessage(`Client #${count} angenommen`);
}, { signal: controller.signal });
// Wichtig · Fallstricke
- Port starten: Wenn du Nachrichten am Port mit
addEventListener("message", …)abonnierst, musst du danachport.start()aufrufen. Beim Setzen vonport.onmessagegeschieht das automatisch. - Kein Ereignis beim Trennen: Schließt ein Tab, erfährt der Worker das nicht. Schicke daher selbst eine Abmeldenachricht (z. B. bei
pagehide) oder prüfe regelmäßig per Heartbeat, ob der Client noch da ist. Sonst füllt sich die Port-Liste mit toten Ports. - Gleiche Herkunft: Nur Dokumente mit derselben Origin und derselben Kombination aus Skript-URL und
nameteilen sich eine Worker-Instanz. Eine anderename-Option startet einen neuen Worker. - Kompatibilität: Shared Workers laufen in Chrome/Edge, Firefox und Safari (ab 16) und gelten seit 2024 als Baseline. Chrome für Android unterstützt sie erst ab Version 145, ältere Versionen gar nicht. Prüfe deshalb mit
typeof SharedWorker !== "undefined"und nutze als Ausweichlösung z. B.BroadcastChannel. - Fehlersuche: Die Konsolenausgaben des Workers stehen nicht in der Konsole des Tabs, sondern z. B. unter
chrome://inspect/#workersbzw.about:debuggingin Firefox.