Noctiluca - リモート制御ソフトウェアの未来はWebRTCではなくQUICだったようです
(drive.google.com)こんにちは、unstablerと申します。初めて記事を書いてみます。
普段あまり文章を書くほうではないので、まとまりのない長文ですがよろしくお願いします!
macOSが嫌いで、むしろmacOSに執着し始めました
私は2011年から主にLinuxデスクトップを使ってきました。Ubuntu、Debian、Fedoraを経て、Arch Linux + KDE PlasmaをメインOSとして使い続けてきました。いろいろな事情があって、2021年からはSI企業のように回る会社を立ち上げ、組み込みC++でも、モバイルアプリでも、単純なWebサイトでも、面白く取り組める仕事なら何でも引き受けてきました。
そうしているうちに、iOSアプリを作る仕事の比重がだんだん大きくなってきました。しかし、Macはあまり使いたくありませんでした。最初はKarabinerでキーバインドをあれこれ変えてみたり、Google リモート デスクトップで接続して作業したりしていましたが、あまりに遅いうえ、Xcodeでキー入力やマウスが一部おかしく動作して大きなストレスでした。
そういえばRDP! xrdpがあった!
ふとRDPを思い出しました。RDPはMicrosoft Windows向けに開発されたプロトコルですが、xrdpというオープンソース実装がありました。ただしxrdpは基本的にX11の利用を前提としており、macOSでは標準の画面共有 + VNCバックエンドの組み合わせが使えたものの、画面解像度が1:1で合わないと、とても実用にならない状態でした。
そこでxrdpのVNCバックエンドとScreenCaptureKitをベースに、'麗 -ulalaca-' というxrdpバックエンドプラグインを作ることになりましたが、実用できるレベルには届きませんでした。
- 最新版のWindows (
mstsc.exe) で消えてしまったGFX (H.264) / RFXサポート:
私が開発を始めた頃には、すでにGFX / RemoteFXコーデックのサポートが外れ始めていました。Linux向けクライアントのFreeRDPには今でもサポートが残っていますが、現在のWindowsではRLEベースの圧縮だけが残っているようです。 - 極悪な開発 / デバッグ難易度: 画面表示機能以外の開発があまりにも難しく、デバッグも非常に大変でした。最初はやる気満々で音声出力やクリップボード同期なども作ってみたかったのですが、ただでさえADHDを抱えていたこともあり、興味が急速に冷めていきました。
WebRTCでもう一度作ってみよう! でも...
ulalacaを放置して約半年後、Noctilucaを構想しながら「WebRTCでもう一度ちゃんと作ってみよう!」と思うようになりました。しかし、WebRTCの実装も一筋縄ではいきませんでした。
- カスタマイズの難しさ: 画面データをビデオソースとして使うために、Google Chromiumのソースコードを取得して修正しなければなりませんでした。コーデックのパラメータを修正したあとにハードウェアエンコードが動かなくなったときは、その理由を知るためにソースコードを掘り回してログを追加し、毎回ビルドし直さなければなりませんでした。
- ポートを固定できない: シグナリングサーバーも必要で、TURN/STUNも必要で、何より送信側ポートの固定もポート再利用もできませんでした。本当に辛かったです。
- SCTPの呪い: WebRTC DataChannelは内部的にSCTPを使います。1つのメッセージのペイロードサイズがMTUより大きくなると、ビデオ / オーディオストリームに遅延が発生し始める問題がありました。
結局、巡り巡ってQUICへ
WebRTCの複雑さに疲れ果て、今回もNoctilucaを半年近く放置してしまいました。カフェでぼーっとして帰る道すがら、ふとHTTP/3の基盤になっているQUICを思い出しました。ちょうどmacOS / iOSでも Network.framework がQUIC実装を提供していたので、既存のソースコードをベースにすぐプロトタイプを作れたのですが、プロトタイプ段階で以下の問題がすぐに解決しました。
-
Head-of-Line Blocking (HOL) の解消: TCPベースのソリューションや、SCTPを使うWebRTC DataChannelの最大の問題は、1つのパケットが失われると後続するすべてのデータが止まってしまうことです。しかしQUICではストリームが独立しています。音声パケットが1つ飛んでも、マウス入力やビデオフレームは流れ続けます。
-
単一UDPポートとConnection Migration: WebRTCのようにシグナリングサーバーやSTUN/TURNを複雑に構成する必要がありませんでした。UDPポートを1つ開ければそれで終わりです。Wi‑Fi APを切り替えても、Connection Migrationのおかげで接続は維持されました。
結論: ベータテスターを募集します!
こうした経緯を持つリモート制御ソフトウェア『Noctiluca』のベータテスターを募集します。
-
QUICベースの『Sirius』という独自設計プロトコルを使用します。
- 近いうちに仕様などが固まり次第、オープンソースで公開する予定です!
-
H.264 / H.265 (HEVC) をサポートします。
- VM環境向けの従来型タイルベース画像コーデック (MJPG, RLE, WebP) もサポートします。
-
HDRコンテンツの伝送をサポートします。 (実験的)
-
クライアント-サーバー間でコーデック要件をネゴシエーションできます。
-
PAM (username-password)、password-only、SSH鍵を使った認証をサポートします。
-
プラグインで機能を拡張できます。今後fail2banなどを実装し、追加機能として提供する予定です。
- プラグインを直接作成して認証メカニズムを拡張できます。
-
クライアントは現在、iOS / macOS版のみ存在します。
- Qt / C++ベースのLinux / Windowsクライアントを開発する予定です!
私のLinuxラップトップでiOSアプリ開発ができるその日まで!
今日も、私のLinuxラップトップに戻るための旅は続きます。
ありがとうございます。
(+ 実はGoogle Driveのリンクをここにそのまま載せてよいのか分からなかったので、とりあえず以前紹介したときに投稿したXポストをリンクとして載せました..!)
- 最初のテスト版のGoogle Driveリンク: https://drive.google.com/drive/folders/1r4m7lGZ-f988dp_piLAEwlJRLPODPNQq?usp=drive_link
(++ Noctilucaを開発しながらバイブコーディングで作った副産物(?)ですが、こちらもよろしくお願いします..!)
- swift-msquic: iOS / macOSでMsQuicをSwiftから簡単に使えるようにしたwrapperモジュールです!
- Xuanxue: SwiftでSSH鍵を使って署名 / 署名検証を行えるようにするモジュールです! あまりに怠け者なので何でも手早く済ませたくて、こんな名前を付けました!
8件のコメント
素晴らしいです!! 👍🏻
Parsecを使っています
モニターサイズが同じでなければならないという制約を除けば、最高のリモート接続ツールだと思います。
iPadに対応していないのは、私にとってはまったく問題ではないので。
私もparsecを使っていますが、本当にモバイルで使えないと知って、ちょっと衝撃を受けた気がします。まさかと思って……(笑)
実際、iOS/macOS開発では、Mac miniやMacBookをKVMでつないで使うのがやっぱり一番いい気もしますが、面倒ではあるんですよね。
実のところ、Noctiluca の開発を続けられるなら、Microsoft RDP の「RemoteApp」コンセプトに似た機能を作ってみたいです。あと、USB リダイレクト機能も!
ThinkPad に iPhone をつないだら、別の部屋にある Mac でもそのまま認識されて、Mac の「フルスクリーン」ではなく Xcode のウィンドウだけを取り出して使えるようになったら、本当に幸せだと思います。
なので、関連する機能も設計・実装中です…!
まだ何も整理できていないので、お見せできるものはこれしかありません ;_;
https://gist.github.com/unstabler/25679baab3a65a3c19f747c38f30c1b3
元のリンクをドライブのリンクに差し替え、Xの投稿リンクは本文内に接続しておきました。
Macにどうやってアクセスするか悩んでいましたが、jetkvmとtailscaleで何とかならないかという漠然とした考えしかありませんでした。
本文の方法なら、kvmがなくても可能そうですね。