Noctiluca – Die Zukunft von Remote-Control-Software war offenbar nicht WebRTC, sondern QUIC
(drive.google.com)Hallo, ich bin unstabler. Ich schreibe zum ersten Mal einen Beitrag.
Normalerweise schreibe ich nicht besonders oft, daher ist es ein etwas ungeordneter und langer Text – ich hoffe trotzdem auf euer freundliches Interesse!
Weil ich macOS nicht mochte, begann ich mich an macOS festzubeißen
Ich nutze seit 2011 hauptsächlich Linux-Desktops. Über Ubuntu, Debian und Fedora bin ich schließlich bei Arch Linux + KDE Plasma gelandet und verwende das bis heute als mein Haupt-OS. Aus verschiedenen Gründen habe ich ab 2021 ein Unternehmen gegründet, das in etwa wie ein SI-Dienstleister arbeitet, und habe alles angenommen, was spannend klang – ob Embedded-C++, mobile Apps oder einfache Websites.
Dabei nahm der Anteil an iOS-App-Entwicklung immer weiter zu. Einen Mac wollte ich aber möglichst nicht benutzen. Anfangs habe ich mit Karabiner die Keybindings hier und da angepasst und mich dann per Google Remote Desktop verbunden, um zu arbeiten, aber das war viel zu langsam, und in Xcode verhielten sich Tastatureingaben und Maus teilweise merkwürdig, was mich sehr gestresst hat.
Da war doch noch RDP! Es gab doch xrdp!
Plötzlich fiel mir RDP wieder ein. RDP wurde zwar als Protokoll für Microsoft Windows entwickelt, aber es gab eine Open-Source-Implementierung namens xrdp. xrdp setzt standardmäßig allerdings X11 voraus, und unter macOS war zwar eine Kombination aus integrierter Bildschirmfreigabe + VNC-Backend möglich, aber sobald die Bildschirmauflösung nicht exakt 1:1 passte, war das praktisch unbenutzbar.
Deshalb habe ich auf Basis des VNC-Backends von xrdp und ScreenCaptureKit ein xrdp-Backend-Plugin namens '麗 -ulalaca- gebaut, aber es hat letztlich kein Niveau erreicht, das für den realen Einsatz gereicht hätte.
- Fehlende GFX- (H.264) / RFX-Unterstützung in aktuellen Windows-Versionen (
mstsc.exe):
Als ich mit der Entwicklung begann, verschwand die Unterstützung für die GFX-/RemoteFX-Codecs bereits nach und nach. Im Linux-Client FreeRDP ist die Unterstützung zwar noch vorhanden, aber in aktuellen Windows-Versionen scheint nur noch RLE-basierte Kompression übrig zu sein. - Extrem hoher Entwicklungs- / Debugging-Aufwand: Außer der Bildausgabe war die Entwicklung insgesamt viel zu schwierig, und auch das Debugging war extrem mühsam. Anfangs war ich noch hochmotiviert und wollte Dinge wie Audioausgabe oder Clipboard-Synchronisierung implementieren, aber da ich ohnehin mit ADHS lebe, war das Interesse schnell wieder verflogen.
Dann eben noch einmal mit WebRTC! Aber...
Nachdem ich ulalaca etwa ein halbes Jahr lang liegen gelassen hatte, kam mir bei der Planung von Noctiluca der Gedanke: „Dann bauen wir es eben noch einmal richtig mit WebRTC!“ Aber auch eine WebRTC-Implementierung war alles andere als einfach.
- Schwierige Anpassbarkeit: Um Bilddaten als Videoquelle zu verwenden, musste ich den Source Code von Google Chromium herunterladen und anpassen. Wenn nach Änderungen an Codec-Parametern die Hardware-Encoding nicht mehr funktionierte, musste ich den Source Code durchforsten, zusätzliche Logs einbauen und jedes Mal neu bauen, nur um den Grund herauszufinden.
- Ports lassen sich nicht fixieren: Man brauchte einen Signaling-Server, dazu TURN/STUN, und vor allem ließ sich der ausgehende Port nicht fest vorgeben und Port-Reuse war ebenfalls nicht möglich. Das war wirklich unerquicklich.
- Der Fluch von SCTP: WebRTC DataChannel verwendet intern SCTP. Wenn die Payload-Größe einer Nachricht größer als die MTU wird, beginnen Video- und Audio-Streams zu laggen.
Am Ende also doch: QUIC
Erschöpft von der Komplexität von WebRTC habe ich auch Noctiluca wieder fast ein halbes Jahr lang liegen lassen. Auf dem Rückweg aus einem Café kam mir dann plötzlich QUIC in den Sinn, die Grundlage von HTTP/3. Da Network.framework unter macOS / iOS ebenfalls eine QUIC-Implementierung bereitstellt, konnte ich auf Basis des bestehenden Source Codes schnell einen Prototyp bauen – und schon auf Prototyp-Niveau waren die folgenden Probleme sofort gelöst.
-
Lösung für Head-of-Line Blocking (HOL): Das größte Problem TCP-basierter Lösungen und auch des WebRTC DataChannel mit SCTP ist, dass beim Verlust eines einzigen Pakets alle nachfolgenden Daten anhalten. Bei QUIC sind die Streams jedoch unabhängig. Selbst wenn ein Audiopaket aussetzt, strömen Mauseingaben oder Videoframes weiter hinein.
-
Ein einzelner UDP-Port und Connection Migration: Anders als bei WebRTC musste ich keine komplexe Konfiguration mit Signaling-Server, STUN oder TURN mehr aufbauen. Es reicht schlicht, einen einzigen UDP-Port zu öffnen. Selbst beim Wechsel des Wi‑Fi-AP blieb die Verbindung dank Connection Migration bestehen.
Fazit: Ich suche Beta-Tester!
Für diese Remote-Control-Software namens „Noctiluca“ mit genau dieser Entstehungsgeschichte suche ich Beta-Tester.
-
Verwendet ein selbst entworfenes QUIC-basiertes Protokoll namens „Sirius“.
- Sobald Spezifikation usw. feststehen, soll es als Open Source veröffentlicht werden!
-
Unterstützt H.264 / H.265 (HEVC).
- Für VM-Umgebungen werden auch klassische tile-basierte Bild-Codecs (MJPG, RLE, WebP) unterstützt.
-
Unterstützt die Übertragung von HDR-Inhalten. (experimentell)
-
Codec-Anforderungen zwischen Client und Server können ausgehandelt werden.
-
Unterstützt Authentifizierung per PAM (username-password), password-only und SSH-Key.
-
Funktionen lassen sich per Plugin erweitern. Später sollen zusätzliche Features wie fail2ban implementiert und bereitgestellt werden.
- Man kann auch selbst Plugins schreiben, um den Authentifizierungsmechanismus zu erweitern.
-
Der Client existiert derzeit nur für iOS / macOS.
- Ein Linux- / Windows-Client auf Basis von Qt / C++ ist geplant!
Bis zu dem Tag, an dem ich iOS-Apps auf meinem Linux-Laptop entwickeln kann!
Auch heute geht meine Reise weiter, wieder zu meinem Linux-Laptop zurückzukehren.
Vielen Dank.
(+ Ehrlich gesagt wusste ich nicht, ob ich hier direkt einen Google-Drive-Link posten darf, deshalb verlinke ich erst einmal den X-Post, den ich damals bei der Vorstellung gepostet habe..!)
- Link zu der ersten Testversion auf Google Drive: https://drive.google.com/drive/folders/1r4m7lGZ-f988dp_piLAEwlJRLPODPNQq?usp=drive_link
(++ Eigentlich ein Nebenprodukt(?), das beim Entwickeln von Noctiluca als Vibe-Coding entstanden ist, aber auch darum würde ich mich freuen..!)
- swift-msquic: Ein Wrapper-Modul, damit sich MsQuic unter iOS / macOS einfach in Swift verwenden lässt!
- Xuanxue: Ein Modul, mit dem sich in Swift Signaturen und Signaturprüfungen mit SSH-Keys durchführen lassen! Ich war einfach zu faul und wollte alles möglichst bequem erledigen, deshalb habe ich ihm diesen Namen gegeben!
8 Kommentare
Großartig!! 👍🏻
Ich nutze Parsec.
Wenn man von der Einschränkung absieht, dass die Monitorgrößen gleich sein müssen, scheint es das beste Tool für den Fernzugriff zu sein.
Dass das iPad nicht unterstützt wird, ist für mich völlig nebensächlich.
Ich nutze auch Parsec, und es hat mich ehrlich gesagt ziemlich schockiert, als ich erfahren habe, dass mobil wirklich nicht geht. Kaum zu glauben ... haha.
Für iOS/macOS-Entwicklung ist es allerdings wohl am besten, einfach einen Mac mini oder ein MacBook per KVM anzuschließen und zu benutzen, auch wenn das etwas umständlich ist.
Wenn ich die Entwicklung von Noctiluca tatsächlich fortsetzen kann, würde ich gern eine Funktion bauen, die dem „RemoteApp“-Konzept von Microsoft RDP ähnelt. Und auch USB-Umleitung!
Wenn ich mein iPhone an mein ThinkPad anschließe und es auf dem Mac im anderen Zimmer genauso erkannt wird, und ich dann nicht den „Vollbild“-Modus des Macs, sondern nur das Xcode-Fenster herausgelöst nutzen könnte, wäre ich wirklich glücklich.
Deshalb entwerfen/implementieren wir gerade auch entsprechende Funktionen..!
Bisher ist noch überhaupt nichts richtig aufbereitet, daher kann ich euch leider nur das hier zeigen ;_;
https://gist.github.com/unstabler/25679baab3a65a3c19f747c38f30c1b3
Den ursprünglichen Link habe ich durch einen Drive-Link ersetzt, und den Link zum X-Post habe ich im Text selbst verknüpft.
Ich habe darüber nachgedacht, wie ich auf meinen Mac zugreifen könnte, aber hatte nur die vage Idee, dass es mit jetkvm und Tailscale irgendwie gehen müsste.
Mit der im Haupttext beschriebenen Methode wäre es dann wohl sogar ohne KVM möglich.