Start · Sprachen · JavaScript · Referenz · SharedWorkerGlobalScope: connect

SharedWorkerGlobalScope: connect

Ereignis

Wird im <code>SharedWorkerGlobalScope</code> ausgelöst, sobald sich ein neuer Client (Tab, Fenster, iframe) per <code>new SharedWorker()</code> mit dem Shared Worker verbindet.

seit JavaScript Baseline 2024: Chrome 4+, Firefox 29+, Safari 16+ Kategorie: webapi

Signatur

self.addEventListener("connect", handler)

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

Typ
void
Beschreibung
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");
Echo: 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"));
{ from: "worker", data: "verbunden", clients: 1 } { from: "worker", data: "Neuer Stand gespeichert", clients: 1 }

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 });
Client #1 angenommen

// Wichtig · Fallstricke

  • Port starten: Wenn du Nachrichten am Port mit addEventListener("message", …) abonnierst, musst du danach port.start() aufrufen. Beim Setzen von port.onmessage geschieht 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 name teilen sich eine Worker-Instanz. Eine andere name-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/#workers bzw. about:debugging in Firefox.