Brynhildr

KeroRemote

リモートデスクトップエンジニアのブログ。

ブラウザ接続について



Verethragnaのブラウザ接続について。




Verethragnaのブラウザ接続を開発中なんですがなんとなく見えてきたのでこの辺で記事をば。

大長編です。

まず、従来のVerethragnaはWindows版のクライアントのみでした。Brynhildrの時はiOS版のKeroRemoteとかQtBrynhildrとかありましたのでクライアントはマルチプラットフォームと言えた感じです。

Verethragnaもかなり前からマルチプラットフォームのクライアントの計画はありまして、ブラウザ版を作ることで対応は可能だと考えブラウザ版の計画は始まったわけです。

が、しかし。

Brynhildrの時はパブリックモードという形で通常の接続方式ではなく暗号化も簡易的な接続方式を作りました。Appleも暗号化の通信に関しては厳しかったのでこーゆー簡易的な感じになったのですが、基本的にTCPでの接続でした。

ただ、Verethragnaでやろーとしてたブラウザ版はTCPではなくその上位レイヤーのHTTPということになります。つまりはブラウザの通信仕様に合わせる感じです。まあ、ブラウザ上で動かす必要があったので最低でもHTMLでJavaScriptは必要になるかなー、程度で考えておりました。

この安易な考えは間もなく叩きつけられます。TCPというかソケットサーバーでHTTPを対応することはそれほど難しくありません。ただここに暗号化(SSL)やリアルタイム通信などが加わってくると話はまるで別物です。手前のソケットサーバーに実装となるとますます大変です。OpenSSLやLibwebsocketsなどを追加していけばいけないこともないのですがメンテナンス性も含めてあまり将来的に変更があるだろうライブラリをリンクさせたくないなとゆー思いがありました。まあVP8やCELTやBlowfishやFastLZは今後も変化はたぶんないでしょうから安心してリンクしてるんですけど。

さて、そんな感じで既に心が砕けそうになってましたが、考え方を変えました。下位モデルと上位モデルを作ることにしました。下位モデルは従来のTCPからのHTTPのみを通信できるモデル、上位モデルはHTTPSやWebSocketなども対応できるモデル、という風にすることにしました。上位モデルはWindowsのカーネルモードドライバーである「HTTP.sys」を利用すればいけそうなことは見えてましたので。まあこのHTTP.sysはこれはこれでサンプルも少ないですしなかなか苦労することになるのですがそれはまた別のお話で・・・。

そんなこんなでまずは下位モデルとゆーことで、開発することになりました。すぐに暗礁に乗り上げますが。

まず、映像で利用する予定だったVP8。これをiOSで描画することができません。正確にはiOSのブラウザのWebKitではVP8を再生できません。WindowsとかAndroidはいけます。まあVP8はGoogleですんで。

さすがにここでH.264系に舵を切ると負けかなと思ってましたのと何よりライセンスが微妙です。例えば、WindowsのDXVAでH.264のエンコードは実装できました。ただ、H.264というかMPEG系の映像圧縮のアルゴリズムをエンコードで利用すると特許利用料(パテント)が発生するのですが、それをMicrosoftが支払っているかというとどうやらそうではないんです。まあOSですし当たり前と言えば当たり前なんですけど法的なとこは個々に対応をってことになってます、OSの規約をみると。

https://www.microsoft.com/en-us/Useterms/OEM/Windows/11/Useterms_OEM_Windows_11_Japanese.htm

大丈夫ですか?御社でご利用のそのH.264での圧縮は。

てことでめんどーなH.264は避けるとして、となるとやっぱりVP8なんですけど、WebAssemblyを利用すればiOSのブラウザでもVP8でデコードできることは確認してました。ならばWebAssemblyと思いましたけど、WebAssemblyはTCPが使えないのでWebSocketを利用する必要がありました。ここでWebSocketかー、ってなりました。将来的にWebAssemblyでもTCPはいけるようになるみたいなんですけど今じゃないと。

そもそもWebKitとゆーかiOSで何とかならんのかと思ってたんですけど、Appleの仕様でiOSのChromeでもWebKitを使うことになってるんで何ともなりなさげ。でも最近ですと欧州でiOSでWebKitに限定しちゃダメってことでChromeのネイティブエンジンがiOSに載るってニュースになりましたよね。これは良い流れ。

https://gigazine.net/news/20240126-ios-17-4-webkit-alternative-browser-engines/

でもまだVP8は動かない。今じゃないと。

てことでそれまで待てないので手っ取り早く考えたのが、JPEGとPNGでハイブリッドにして描画する形式。HTMLのIMGタグの中身を高速に書き換えてやればいけるんじゃないかと。でも実際にはNGでPNGを利用するのは差分で描画するのことが必要でよーわ透過で描画できないIMGタグはNG。透過ができないと画面に動きがなくても常時JPEGででかめの通信量が発生してしまうので面白くない。てことで何とか透過はできないものかと探していたらありましたCanvas。

CanvasはHTML5の時に出てきてまあ今はHTML5とは呼ばないんですけど使える描画コントロール。透過もいけるになりより書き換えが不要でよーわMotionJPEGみたいにストリーミングで流せる。これは良い。ただ、JPEGは画質が良くなくて何とかしたかった。PNGは可逆だけどデータ量がでかいし。

そこで登場したのがWebP。JPEGの代わりにこれでいこうかと。Libwebp で色々試してみたけど良い感じ。で、調べていくとこのWebPってVP8のよーわキーフレーム(Iフレーム)なんです。てことはですよ、Verethragnaで利用しているVP8のライブラリからもWebP形式を生成できるのではと思って色々とやってみてたらできました。これは最高すぎる。てことでCanvasには動きがあればWebP、動きがなければPNGとゆー仕様になりました。

さらに開発を進めるとまた難関が。映像と音声はFetchを使ってサーバーからのストリームにしたのですが、マウスとキーボードの入力はサーバーへのストリームにしないといけない。Fetch Upload Streamingを使わねばならん。だがしかしまたもiOSでは非対応。またか。てことで連続でGETを投げるしかない。で、やってみたんですけどどーやらFetchよりもXMLHttpRequest (Ajax)の方が高速。これは良い。迷いもなくXMLHttpRequestに。

ちなみに、これは最近なんですけどサーバー側のソケットでacceptを使ってたんですけどAcceptEXの方がすげーよってMicosoftのサイトに書いてあったのでそーすることにしました。ApacheのサイトにはBSDのacceptよりもすげーって書いてあったので間違いないですよね。

https://httpd.apache.org/docs/2.2/ja/mod/mpm_winnt.html

これ、接続を受ける際にちょっと仕組みが異なっていてTCPでもHTTPでも使い勝手が良かったのでVerethragnaの次回バージョンアップで実装されてしまいます。

てことで入力系はサーバー側の修正もあり連続GET(のちに連続POSTに変更)のパターンです。いずれFetch Upload Streamingが対応すればこっちを使いたいんですけど今じゃないと。

あと音声なんですけど圧縮ができません。たぶんMP3とかAACとか使えばできるんですけどサーバー側も対応しなきゃなんで、これは下位モデルですし、とりあえずPCMでモノラルにしました。だいぶ心が負けてきております、この時点で。

あとCanvasの仕様でさっきのPNGの差分描画の時に縮小されているとちゃんと差分で描画できません。だー、こんにゃろー。ちゃんとしてくれー。ゴミがどーしても残ってしまうので一定間隔でWebPによる画面更新を余儀なくされております。

あと暗号化はできないので排他的論理和でハッシュ化程度です。必要であればVPNなどの回線の方で暗号化してくださいお願いします・・・。

そんなこんなで下位モデルはこんな感じで後半はグダグダで開発されましたが、まあでもちゃんと動くよーに頑張ってはおりますのでー。JavaScriptとゆーかHTMLファイルでのスクリプトはユーザー側でも作れるよーにしたいと思ってますので、Brynhildrのパブリックモードのよーに自由にクライアントを作ることができればと考えております。自分が作ったのはあくまでもサンプル・・・サンプルなんですよ、ドーン!的な。いやホントだいぶしんどいです、JavaScript。

で、上位モデルのHTTP.sysはSSL(HTTPS)もいけるわWebSocketもいけるわ、であればWebAssemblyもいけるわ、でもちろんVP8もCELTも入力系のストリーミング化もできるし何でもござれなんですよね。いやまだ全然コアの部分しかできてないんですけど。まあ希望しかないですよね、下位モデルはずいぶん大変でしたもので特に。

その頃にはiOSでもVP8がネイティブで対応できてるかもしれないですし、WebAssemblyでTCPがいけるかもしれないですしとか状況は変わってるかもしれないんですけどねーー。

あと、1つHTTPで非暗号化で良いところは、プロキシへの対応ですかね。恐らくWebSocketもSSLと同じくプロキシの対応が難しいと思うんですよね。WebSocketも厳密にはHTTPではないのでSSLと同じ中身は分からんのでポート開けたるからそこへどうぞってことになると思うので。大丈夫ですかね、そーゆー面でのセキュリティ。その辺、下位モデルのHTTPであればFetchとかであれば逆にちゃんと中身も確認できると思いますので安心かなと。空港の保安検査場的な。

そもそも最近は何でもかんでも暗号化暗号化で中身が分からんので安心かもしれないですけど、もし情報が漏洩しても中身が分からんから漏洩してても分からんとかゆーこともありホントにそれはそれで大丈夫なのk

はい、話が逸れ始めましたし長文になりましたしこの辺で。

てことでVerethragnaのブラウザ接続は開発順調?ですんでもう少々お待ちください!


8件のコメント ... ( 管理人承認制 )



最新のSafariではVP8とVP9をサポートしたという話でしたがWebkitを使わない実装なんでしょうかね
Safariがサポートしたのなら今後Webkitが対応する可能性もありそうですね


匿名  2024/06/19


> 最新のSafariではVP8とVP9をサポート


macOSのSafariではサポートされたみたいなんですがiOSの方はまだなんですよね。あと1つ気になるのはSafariのVP8はWebMコンテナでの対応でしてVerethragnaはWebMのコンテナは使ってないのでその辺の面倒さはありまして。ですのでスムーズにVP8に対応させるにはWebAssemblyの方かなとは考えております。よろしくお願いいたします。


KANEKO  2024/06/20


ChromebookではクライアントがWebアプリのリモートデスクトップアプリを使いたいですが選択肢が少ないので、リリースを心待ちにしております。


匿名  2024/06/21


ありがとうございます!がんばります!


KANEKO  2024/06/21


WebRTCを使えばいいのでは?
サーバー側はlibdatachannel を使えば簡単


匿名  2024/07/24


そうなんです、WebRTCを使えば実装自体は簡単なんです。
プライベートユースであればそれでも良いかと思うのですが、ビジネスユースを想定しますとカスタマイズが伴いますので責任やコストなども考慮する必要があり、その場合はWebRTCをコアにするのはなかなかリスクがありましたので、機能を必要最小限に絞って自前で作っている次第でございます、恐れ入ります。
libdatachannelは存じ上げませんでした、参考になります。
ありがとうございます!


KANEKO  2024/07/25


記事を拝見させていただきました。お忙しいところ恐れ入りますが、現在調整などを行っていらっしゃるのでしょうか。対応コーデックなどによる問題が発生しているとのことですが、それを自作されるとは驚きです。どの分野を学べば、そのような技術を身に付けられるのでしょうか。笑


匿名  2024/08/15


今ちょっとブラウザ接続の開発作業が止まっておりまして、恐れ入ります。大きなものから小さなものまでまだまだ課題が残っている状況ではございますので今暫くかかりそうなのですが手段はまだありそうですので時間を見つけて模索する予定でございます。そんな感じで色々と試行錯誤してますが、枠にはまらない開発手法は昔からの性分でして、安定して高速に動くのであれば手段を問わず、をモットーに開発しております。ですので課題が発生したらそれについて解決方法を調べて実装の繰り返しで何とかなっている感じでございます。欲しい技術情報は都度インターネットで見つけてますw


KANEKO  2024/08/16




... 不具合報告の際は、アプリのバージョンやOS等の動作環境の記載を御願い致します。

表記されている会社名・製品名・システム名などは、各社の商標、または登録商標です。
当サイトはAmazon.co.jpアソシエイトプログラムに参加しています。
© 2010-2024 LAUNCELOT CO. LTD.