View a markdown version of this page

Integrieren Sie Ihre Webanwendung mit der WebRTC-Umleitung - Amazon WorkSpaces

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Integrieren Sie Ihre Webanwendung mit der WebRTC-Umleitung

Die WebRTC-Umleitung ermöglicht es Webanwendungen, die innerhalb von WorkSpaces Sitzungen ausgeführt werden, native clientseitige Audiogeräte zu verwenden. In diesem Thema erfahren Entwickler von Webanwendungen, wie sie die WebRTC-Umleitungsumgebung erkennen und in sie integrieren können.

Wenn die WebRTC-Umleitung auf einem aktiviert ist WorkSpace, fügt die Browsererweiterung Amazon DCV WebRTC Redirection ein Proxy-SDK in die Webseite ein. Ihre Anwendung kann diesen Proxy erkennen und ihn verwenden, um standardmäßige WebRTC-API-Aufrufe — einschließlich get UserMedia und RTCPeerConnection — an die lokalen Geräte des Benutzers und nicht an die virtuellen Geräte der Fernbedienung WorkSpace weiterzuleiten. Dies bietet im Vergleich zum Streamen von Medien über das DCV-Displayprotokoll eine deutlich bessere Leistung und eine geringere Latenz.

Ihre Anwendung muss beide Fälle behandeln: wenn sie in einem WorkSpace mit aktivierter WebRTC-Umleitung ausgeführt wird, und wenn sie in einem Standardbrowser ohne WebRTC-Umleitung ausgeführt wird. Der Proxy ist optional — wenn er nicht vorhanden ist, kann Ihre Anwendung auf das Standard-WebRTC zurückgreifen.

Voraussetzungen

Für Endanwender

Endbenutzer benötigen Folgendes:

Für Entwickler

Ihre Webanwendung muss:

  • Verwenden Sie Standard-WebRTC-APIs (wie get UserMedia and) RTCPeerConnection

  • Fügen Sie Erkennungs- und Initialisierungscode hinzu, wie in diesem Thema beschrieben

Wie integriert man

Die Integration umfasst vier Schritte: Erkennen der Umleitungsumgebung, Überschreiben von WebRTC-APIs, Zuordnen von Audioelementen und Herstellen der Wiederverbindung.

Schritt 1: Ermitteln Sie die Umleitungsumgebung

Fügen Sie diesen Initialisierungscode zu Ihrer Anwendung hinzu. Der Callback wird ausgeführt, wenn der Proxy bereit ist, oder nach Ablauf des Timeouts, wenn die Umleitung nicht verfügbar ist.

let proxy = null; function handleInitCallback(result) { if (result.success) { // Redirection is available proxy = result.proxy; console.log('WebRTC redirection enabled, version:', proxy.getVersion()); console.log('Client info:', proxy.clientInfo); // Override WebRTC APIs to use redirection proxy.overrideWebRTC(); // Set up reconnection handling setupReconnectionHandling(); } else { // Not in a redirection environment - use standard WebRTC console.log('WebRTC redirection not available:', result.error); } } // Register the initialization callback if (globalThis.DCVWebRTCPeerConnectionProxyV2) { globalThis.DCVWebRTCPeerConnectionProxyV2.setInitCallback(handleInitCallback, 5000); }

Die wichtigsten Punkte:

  • Suchen Sie nachglobalThis.DCVWebRTCPeerConnectionProxyV2, um die Erweiterung zu erkennen

  • Rufen Sie setInitCallback() Ihren Handler an und legen Sie einen Timeout von 5000 ms fest

  • Der Callback empfängt ein Ergebnisobjekt mit einem success booleschen Wert und entweder oder proxy error

  • Aufruf proxy.overrideWebRTC() zur Weiterleitung von Standard-WebRTC-APIs

Schritt 2: Verwenden Sie Standard-WebRTC-APIs

Verwenden Sie nach dem overrideWebRTC() Aufrufen die WebRTC-APIs normal. Der Proxy leitet sie transparent an den lokalen Client weiter.

Anmerkung

Die Videoumleitung wird derzeit nicht unterstützt. getUserMediaAnfragen video: false eingeben.

// Get user media - automatically redirected const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false // Video redirection not yet supported }); // Create peer connection - automatically redirected const pc = new RTCPeerConnection(configuration); // Everything else works as standard WebRTC pc.addTrack(stream.getAudioTracks()[0], stream); const offer = await pc.createOffer(); await pc.setLocalDescription(offer);

Wenn Sie auf die ursprünglichen Browser-APIs zugreifen müssen (z. B. um Videos vom Remote-Browser und nicht vom lokalen Client aufzunehmen), werden sie gespeichert inproxy.overridenApis:

// Get the original getUserMedia (runs in remote browser, not redirected) const originalGetUserMedia = proxy.overridenApis.get('navigator.mediaDevices.getUserMedia'); // Available original APIs: // 'navigator.mediaDevices.getUserMedia' // 'navigator.mediaDevices.addEventListener' // 'navigator.mediaDevices.removeEventListener' // 'navigator.mediaDevices.enumerateDevices' // 'navigator.mediaDevices.getDisplayMedia' // 'window.RTCPeerConnection' // 'window.RTCPeerConnection.generateCertificate' // 'window.AudioContext' // 'window.Worker' (experimental) const remoteStream = await originalGetUserMedia.call(navigator.mediaDevices, { audio: false, video: true });

Schritt 3: Audioelemente zuordnen

Rufen Sie für die Audiowiedergabe an, mapAudioElement() bevor Sie ein Audioelement einstellensrcObject.

const audioElement = document.querySelector('audio#remote-audio'); // Map the audio element before setting srcObject proxy.mapAudioElement(audioElement); // Now use the audio element normally audioElement.srcObject = remoteStream; await audioElement.play(); // Control playback audioElement.pause(); audioElement.volume = 0.8; audioElement.muted = false; // Change output device await audioElement.setSinkId(deviceId);

Schritt 4: Stellen Sie die Verbindung wieder her

Der Umleitungsdienst kann vorübergehend nicht verfügbar sein, z. B. aufgrund von Netzwerkproblemen oder der Wiederverbindung von Clients.

Wichtig

Nach der Wiederverbindung werden alle zuvor erstellten Proxyobjekte ungültig, da der Client-Browser-Kontext vollständig neu geladen wird. Sie müssen bestehende Verbindungen schließen und neue WebRTC-Objekte erstellen.

function setupReconnectionHandling() { proxy.addStatusChangeEventListener((event) => { switch (event.status) { case 'unavailable': console.error('Redirection lost'); handleRedirectionLost(); break; case 'available': console.info('Redirection restored'); handleRedirectionRestored(); break; } }); } function handleRedirectionLost() { // Try to close cleanly - proxies may throw exceptions after reconnection try { if (peerConnection) { peerConnection.close(); } } catch (error) { console.warn('Error closing peer connection (proxy may be invalid):', error); } showReconnectingMessage(); } function handleRedirectionRestored() { // IMPORTANT: All existing proxy objects are invalid after reconnection. // Create new RTCPeerConnection, MediaStream, and other WebRTC objects. hideReconnectingMessage(); restartCall(); // Must create fresh WebRTC objects }

Sie können das Heartbeat-Timing anpassen:

proxy.resetHeartbeat({ heartbeatTimeoutMs: 5000, // Time before marking unavailable heartbeatIntervalPeriodMs: 500 // How often to check });

Geräteaufzählung

Geräteänderungen — z. B. wenn ein Benutzer ein Headset anschließt — werden automatisch erkannt. Wird verwendetmakeMediaDevicesProxy(), um auf dem lokalen Client auf Geräteänderungen zu warten:

const mediaDevices = proxy.makeMediaDevicesProxy(); mediaDevices.ondevicechange = async () => { const devices = await navigator.mediaDevices.enumerateDevices(); updateDeviceList(devices); };

Wird verwendetproxy.clientInfo, um festzustellen, von welcher Client-Plattform aus der Benutzer eine Verbindung herstellt:

// clientInfo contains: // - platform: 'web' | 'windows' | 'macOS' | 'linux' // - version: SDK version string // - userAgent: browser user agent string // - browserDetails: { browser: string, version: string } switch (proxy.clientInfo.platform) { case 'web': console.log('Connecting from web client'); break; case 'windows': console.log('Connecting from Windows native client'); break; case 'macOS': console.log('Connecting from macOS native client'); break; case 'linux': console.log('Connecting from Linux native client'); break; }

Fortgeschritten: Audioverarbeitung mit der Web-Audio-API

Sie können die Web-Audio-API verwenden, um Audiostreams zu verarbeiten, bevor Sie sie über eine Peer-Verbindung senden:

const audioContext = new AudioContext(); const source = audioContext.createMediaStreamSource(micStream); const gainNode = audioContext.createGain(); const destination = audioContext.createMediaStreamDestination(); source.connect(gainNode); gainNode.connect(destination); // Control microphone volume gainNode.gain.value = 0.5; // 50% volume // Use the processed stream pc.addTrack(destination.stream.getAudioTracks()[0], destination.stream);

Vollständiges Beispiel

Das folgende Beispiel zeigt eine vollständige Integration mit Initialisierung, Wiederverbindungsbehandlung, Erkennung von Geräteänderungen und Anrufeinrichtung:

let proxy = null; let peerConnection = null; let localStream = null; function initializeRedirection() { if (globalThis.DCVWebRTCPeerConnectionProxyV2) { globalThis.DCVWebRTCPeerConnectionProxyV2.setInitCallback((result) => { if (result.success) { proxy = result.proxy; proxy.overrideWebRTC(); proxy.addStatusChangeEventListener(handleStatusChange); proxy.resetHeartbeat({ heartbeatTimeoutMs: 5000, heartbeatIntervalPeriodMs: 500 }); setupDeviceChangeListener(); } else { console.log('Redirection not available:', result.error); } }, 5000); } } function handleStatusChange(event) { if (event.status === 'unavailable') { try { if (peerConnection) { peerConnection.close(); peerConnection = null; } if (localStream) { localStream.getTracks().forEach(t => t.stop()); localStream = null; } } catch (error) { console.warn('Error cleaning up (proxies invalid):', error); peerConnection = null; localStream = null; } } else if (event.status === 'available') { startCall(); // Create fresh WebRTC objects } } function setupDeviceChangeListener() { const mediaDevices = proxy.makeMediaDevicesProxy(); mediaDevices.ondevicechange = async () => { const devices = await navigator.mediaDevices.enumerateDevices(); updateDeviceUI(devices); }; } async function startCall() { try { localStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false }); peerConnection = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }); localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream)); peerConnection.ontrack = (event) => { const remoteAudio = document.querySelector('audio#remote'); if (proxy) { proxy.mapAudioElement(remoteAudio); } remoteAudio.srcObject = event.streams[0]; remoteAudio.play(); }; peerConnection.onicecandidate = (event) => { if (event.candidate) { sendToSignalingServer({ type: 'ice-candidate', candidate: event.candidate }); } }; const offer = await peerConnection.createOffer(); await peerConnection.setLocalDescription(offer); sendToSignalingServer({ type: 'offer', sdp: offer }); } catch (error) { console.error('Failed to start call:', error); } } initializeRedirection();

Testen Sie Ihre Integration

Ohne Umleitung

Ihre Anwendung funktioniert normal, wenn die Erweiterung nicht installiert ist, wenn sie außerhalb einer WorkSpace ausgeführt wird oder wenn die WebRTC-Umleitung nicht über die Gruppenrichtlinie aktiviert ist. Testen Sie, indem Sie Ihre Anwendung in einem normalen Browser öffnen.

Mit Umleitung

So testen Sie mit aktivierter Umleitung:

  1. Erstellen Sie ein WorkSpace DCV-Protokoll und aktivieren Sie die Gruppenrichtlinieneinstellung für die WebRTC-Umleitung. Siehe Verwalte dein Windows WorkSpaces in WorkSpaces Personal.

  2. Laden Sie einen WorkSpaces Client von clients.amazonworkspaces.com herunter, installieren Sie ihn und stellen Sie eine Verbindung zum her. WorkSpace Stellen Sie sicher, dass die Chrome- oder Edge-Erweiterung installiert ist (automatisch, wenn das GPO festgelegt ist).

  3. Öffnen Sie Ihre Webanwendung im WorkSpace Browser. Suchen Sie in der Konsole nach der Meldung „WebRTC-Umleitung aktiviert“. Überprüfen Sie die Audiofunktionalität mit lokalen Geräten, testen Sie die Gerätenumeration und das Switching und überprüfen Sie die Handhabung der Verbindungswiederverbindung.

Bewährte Methoden

Beachten Sie bei der Integration mit der WebRTC-Umleitung die folgenden Empfehlungen:

  • Prüfen Sie immer, ob die Umleitung verfügbar ist — gehen Sie niemals davon aus, dass der Proxy existiert

  • Rufen Sie overrideWebRTC() früh an — bevor Sie irgendwelche WebRTC-Objekte erstellen

  • Ordnen Sie Audioelemente vor der Verwendung zu — rufen mapAudioElement() Sie sie vor der Einstellung auf srcObject

  • Wiederverbindung handhaben — nach der Wiederverbindung sind alle Proxyobjekte ungültig; erstellen Sie immer neue WebRTC-Objekte

  • Testen Sie beide Modi — stellen Sie sicher, dass Ihre App mit und ohne Umleitung korrekt funktioniert

  • Verwenden Sie Standard-WebRTC-APIs — der Proxy leitet sie transparent weiter; für die grundlegende Verwendung sind keine benutzerdefinierten APIs erforderlich

  • Ressourcen bereinigen — Event-Listener entfernen und Verbindungen schließen, wenn Sie fertig sind

Fehlerbehebung

Umleitung wurde nicht erkannt

  • Stellen Sie sicher, dass die Browsererweiterung installiert und aktiviert ist (überprüfenchrome://extensions)

  • Vergewissern Sie sich, dass die Gruppenrichtlinie für die WebRTC-Umleitung aktiviert ist auf WorkSpace

  • Stellen Sie sicher, dass Sie ein DCV-Protokoll verwenden WorkSpace

  • Suchen Sie in der Browserkonsole nach Initialisierungsmeldungen

  • Stellen Sie sicher, dass die WorkSpaces Client-Version die WebRTC-Umleitung unterstützt (Windows 5.21.0 oder höher, macOS 5.31.0 oder höher, Linux 2026.0 oder höher oder Webclient)

Audio oder Video funktionieren nicht

  • Verify overrideWebRTC() wurde aufgerufen, bevor WebRTC-Objekte erstellt wurden

  • Stellen Sie vor der Einstellung sicher, dass die Audioelemente zugeordnet sind mapAudioElement() srcObject

  • Überprüfen Sie die Browserkonsole auf Fehler

  • Stellen Sie sicher, dass Geräteberechtigungen erteilt wurden

Probleme bei der Wiederverbindung

  • Implementieren SieaddStatusChangeEventListener(), um Verfügbarkeitsänderungen zu erkennen

  • Erstellen Sie nach der Wiederverbindung immer neue MediaStream Objekte. Alte Proxys sind ungültig RTCPeerConnection und werden ausgelöst

  • Überprüfen Sie die Heartbeat-Konfiguration, wenn die Nichtverfügbarkeit zu langsam oder zu schnell erkannt wird

API-Referenz

Im Folgenden wird die Proxy-API zusammengefasst:

interface DCVWebRTCProxy { // Version and client info getVersion(): string; clientInfo: { platform: 'web' | 'windows' | 'macOS' | 'linux'; version: string; userAgent: string; browserDetails: { browser: string; version: string; }; }; // Core methods overrideWebRTC(): void; mapAudioElement(element: HTMLAudioElement): void; // Device management makeMediaDevicesProxy(): MediaDevices; // Status monitoring addStatusChangeEventListener(callback: (event: StatusChangeEvent) => void): void; resetHeartbeat(config: { heartbeatTimeoutMs: number, heartbeatIntervalPeriodMs: number }): void; // Access original (non-redirected) browser APIs overridenApis: Map<string, Function>; } interface StatusChangeEvent { status: 'available' | 'unavailable'; lastHeartbeat?: number; }