Signatur
Beschreibung
PresentationConnection ist das Herzstück der Presentation API. Ein Objekt dieser Schnittstelle steht für den bidirektionalen Kanal zwischen der steuernden Seite (Controller, etwa ein Laptop-Browser) und der empfangenden Seite (Receiver, etwa ein Chromecast, ein Beamer oder ein zweiter Monitor). Über diesen Kanal schicken beide Seiten Nachrichten als Zeichenketten oder Binärdaten hin und her – ähnlich wie bei einem WebSocket.
Man erzeugt die Verbindung nicht selbst. Auf der steuernden Seite bekommt man sie als Ergebnis von PresentationRequest.prototype.start() oder reconnect(). Auf der empfangenden Seite liefert sie navigator.presentation.receiver.connectionList. Wichtige Eigenschaften:
id– eindeutige Kennung der Präsentation (fürreconnect()merken)url– URL der präsentierten Seitestate–"connecting","connected","closed"oder"terminated"binaryType–"arraybuffer"oder"blob"für empfangene Binärdaten
Die Methoden sind send(data) (Nachricht senden), close() (Verbindung trennen, die Präsentation läuft aber weiter) und terminate() (Präsentation ganz beenden). Die Ereignisse connect, close, terminate und message melden Statuswechsel und eingehende Daten. Sie lassen sich per addEventListener oder über onconnect, onclose, onterminate und onmessage abonnieren.
Typische Einsatzfälle sind Folienpräsentationen, die man vom Laptop aus steuert, Videos auf einem Cast-Gerät oder Spiele, bei denen das Smartphone als Controller dient.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $data Pflicht | string | ArrayBuffer | ArrayBufferView | Blob | Parameter von send(data): die Nachricht an die Gegenseite. Objekte vorher mit JSON.stringify() in eine Zeichenkette umwandeln. |
Rückgabewert
PresentationRequest.start() und reconnect() als Promise<PresentationConnection> oder die connectionList des Receivers. send(), close() und terminate() geben undefined zurück.Beispiele
Präsentation starten und Nachrichten austauschen (Controller)
const request = new PresentationRequest(['/slides/receiver.html']);
const startButton = document.querySelector('#start');
startButton.addEventListener('click', async () => {
try {
// Muss durch eine Nutzeraktion ausgelöst werden
const connection = await request.start();
localStorage.setItem('presId', connection.id);
connection.addEventListener('connect', () => {
console.log('Verbunden:', connection.state);
connection.send(JSON.stringify({ type: 'goto', slide: 1 }));
});
connection.addEventListener('message', (event) => {
console.log('Antwort vom Receiver:', event.data);
});
connection.onclose = (event) => {
console.log('Getrennt:', event.reason, event.message);
};
} catch (err) {
console.error('Start fehlgeschlagen:', err.name);
}
});
Nachrichten auf der Empfängerseite verarbeiten (Receiver)
// In receiver.html, die auf dem zweiten Bildschirm läuft
const setupConnection = (connection) => {
connection.addEventListener('message', (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'goto') {
document.querySelector('#slide').textContent = `Folie ${msg.slide}`;
connection.send(JSON.stringify({ type: 'ack', slide: msg.slide }));
}
});
};
const list = await navigator.presentation.receiver.connectionList;
list.connections.forEach(setupConnection);
// Später hinzukommende Controller ebenfalls einbinden
list.addEventListener('connectionavailable', (e) => setupConnection(e.connection));
Wiederverbinden, trennen und beenden
const request = new PresentationRequest(['/slides/receiver.html']);
const savedId = localStorage.getItem('presId');
const connection = savedId ? await request.reconnect(savedId) : null;
const handleTerminate = () => {
console.log('Präsentation beendet');
localStorage.removeItem('presId');
};
if (connection) {
connection.addEventListener('terminate', handleTerminate);
// Nur die Verbindung trennen, der Receiver läuft weiter
document.querySelector('#disconnect').onclick = () => connection.close();
// Präsentation auf dem Zweitbildschirm vollständig beenden
document.querySelector('#stop').onclick = () => {
if (connection.state === 'connected' || connection.state === 'connecting') {
connection.terminate();
}
};
}
// Wichtig · Fallstricke
- Browser-Unterstützung: Die API ist experimentell und nur in Chromium-Browsern umgesetzt (Chrome, Edge, teils Android/Cast). Firefox und Safari unterstützen sie nicht. Vorher mit
'PresentationRequest' in windowprüfen und eine Ausweichlösung anbieten. - Nur sicherer Kontext: Die API funktioniert nur über HTTPS.
start()braucht außerdem eine Nutzeraktion (transient activation), sonst wird die Promise mitInvalidAccessErrorabgelehnt. Bricht der Nutzer die Geräteauswahl ab, gibt es einenNotAllowedError. send()nur im Zustandconnected: In jedem anderen Zustand wirftsend()einenInvalidStateError. Senden Sie daher erst nach dem Ereignisconnect.close()undterminate()unterscheiden:close()trennt nur die Verbindung, danach istreconnect(id)möglich.terminate()beendet die Präsentation für alle verbundenen Controller.- Sicherheit: Eingehende Nachrichten sind nicht vertrauenswürdig. JSON-Daten prüfen und Inhalte nicht ungefiltert per
innerHTMLeinfügen (XSS-Gefahr). - Das
close-Ereignis ist einPresentationConnectionCloseEventmitreason("error","closed","wentaway") undmessage.