純粋なHTTPの力 – 画面共有、リアルタイムメッセージング、SSH、VNC
太田亮
公開日:2020年12月17日・更新日:2021年7月21日
こんにちはみんな。今日は、純粋なHTTPストリームのパワーについて紹介したいと思います。画面共有やビデオチャット、リアルタイムのテキストメッセージング、SSH、VNCなどができるんです。下のデモ動画は、純粋なHTTPを通じたSSHとVNCを示しています。さあ、詳しく見ていきましょう!
なぜHTTPなのか?
HTTPは、どんな状況でも通信ができるように、どこにでも使われています。HTTPは最も成熟したプロトコルの一つで広く使われています。Windows、Mac、Linuxの個人用コンピュータ、Android、iPhone、iPadを含むスマートフォンやタブレットのWebブラウザ、ターミナルのcurl
、wget
コマンド、IoTデバイス、ショートカット iOSアプリやMicrosoft Flowのような自動化ツール、Webフックなどで、HTTPを見つけることができます。さらに、HTTPはHTTP/2、HTTP/3と進化し、速くなっています。
通常、HTTPリクエストは寿命が短く、HTML/CSS/JavaScriptやメディア、APIリクエストの取得に使われます。この記事では、WebSocketやWebRTCなしで、純粋なHTTPストリームを通じてリアルタイム通信を行う長寿命のHTTPリクエストについて紹介します。
Piping Server
私は、Piping Serverを作りました。これにより、すべてのデバイス間でデータを転送することができます。
パイプやブラウザを介して純粋なHTTPでデバイス間の無限転送
無限にデバイス間の転送をHTTP/HTTPSで行うことができます。
転送
Piping Serverはシンプルです。以下のように転送することができます。
# 送信する
echo 'hello, world' | curl -T - https://ppng.io/hello
# 受け取る
curl https://ppng.io/hello > hello.txt
Piping Serverは、POST /hello
やPUT /hello
のデータをGET /hello
に転送します。パス/hello
は、/mypath
や/mypath/123/
のように何でも構いません。同じパスを指定した送信者と受信者が転送を行います。送信者と受信者のどちらかが先に転送を始めることができます。最初の人が他の人を待ちます。
また、https://ppng.ioのようなWeb UIをブラウザで使用することもできます。より現代的なUIは、https://piping-ui.orgで見つけることができ、E2E暗号化もサポートしています。
ストリーム
最も重要なのは、データがストリーミングされることです。これは、どんなデータでも無限に転送できることを意味します。以下のデモではseq inf
を使って無限のテキストストリームを転送しています。
考えられること
…
Piping Serverはシンプルです。/hello
のような同じパスを指定した送信者と受信者が転送を行います。以下の画像は転送のコンセプトを示しています。
画像は、POST /mypath
で送信者が、受信者が/mypath
をGET
して転送できることを示しています。送信者と受信者はどちらも最初に転送を開始できます。最初に動き出した方がもう一方を待ちます。Piping Serverでは、POSTメソッドとPUTメソッドは同じです。
以下のようなJavaScriptでfetch()
を使ってテキストを転送できます。
// 送信
fetch("https://ppng.io/hello", {
method: "POST",
body: "hello, world"
});
// 受け取る
const res = await fetch("https://ppng.io/hello");
console.log(await res.text());
// => "hello, world"
以下のようにcurl
コマンドでも使用できます。
また、以下のように画像やビデオなどのバイナリデータも転送することができます。受信者はURLをブラウザで開いて、画像を取得していることがわかります。
HTTPは至るところにあります。ですから、余計なツールがなくても自由にデータを転送することができます。
無限に転送する
Piping Serverの最も注目すべき特徴は、無限にデータを転送できることです。以下のデモはウェブブラウザにテキストストリームを入力している様子を示しています。
フォルダーを送信する
以下のように複数のファイルが含まれるフォルダー(ディレクトリ)を転送することができます。
# フォルダーを送信
tar c ./mydir | curl -T - https://ppng.io/mypath
# フォルダを取得
curl https://ppng.io/mypath | tar xv
ファイルは、送信者側でアップロードしながらパッキングされ、受信者側でダウンロードしながらアンパックされます。ストリームにより、一時ファイルを作成せずにこれを可能にします。
エンドツーエンドでデータを暗号化して転送することも簡単です。
- 送信:
... | openssl aes-256-cbc | curl -T ...
- 受け取る:
curl ... | openssl aes-256-cbc -d
圧縮してサイズを減らすことも簡単です。
- 送信:
... | gzip | curl -T ...
- 受け取る:
curl ... | zcat
gpg
やzip
、将来発明されるツールなど、自分の好きなようにデータを変換することができます。パイプを組み合わせることは、時間とメモリの両方の点で効率的です。Unixのパイプはソフトウェアを組み合わせる素晴らしい方法です。Piping Serverの名前はUnixのパイプに由来しています。
Piping Serverの最も一般的な使用例はファイル転送です。ファイルを転送するには、Piping UIを使用できます。これを使うと、エンドツーエンド暗号化で多くのデバイスに安全に転送できます。
長時間にわたって巨大なデータを転送する
こちらは、ローカルとリモートのPiping Serverを使用してHTTP経由でデータを転送するためのシンプルな実験です。
以下のデモビデオは、リモートPiping Server経由でHTTPを通じて45TBが2092時間(87日間)転送される様子を示しています。使用されているのはcat /dev/zero | curl -T- ...
です。
以下の画像は、ローカルPiping Server経由でHTTPを通じて64日間で1110TB(≈ 1PB)が転送されたことを示しています。
これらの実験は、単一のHTTPリクエストで大量のデータを連続して転送でき、単一のHTTPリクエストが十分に長生きすることを示しています。
ウェブブラウザ向け無限ストリーム
ついに、HTTPを介した無限ストリームの送信がウェブブラウザにやってきました!
Google Chrome 85以降にこの機能がオリジントライアルとしてあります。chrome://flags
を開いて、次のように「実験的なWebプラットフォーム機能」を有効にします。
他のメインブラウザであるFirefoxやSafariもこの機能に興味を持っています。
アップロード中のReadableStream本体からリクエストを作成する方法 - whatwg / fetch
要するに、この機能により、以下のようにReadableStream
を送信できます。
fetch("https://example.com", {
method: "POST",
body: <ここにReadableStream!>
});
シンプルなテキストメッセージング
fetch()
とReadableStream
を使って、Webブラウザでシンプルなテキストメッセージングを行います。
以下のコードは、ユーザー入力からReadableStream
を生成し、入力ストリームをPiping Serverに送信します。受信者はブラウザでURLを開き、ストリーミングされたテキストメッセージを見ることができます。
const readableStream = new ReadableStream({
start(ctrl) {
const encoder = new TextEncoder();
window.myinput.onkeyup = (ev) => {
if (ev.key === 'Enter') {
ctrl.enqueue(encoder.encode<br><br>こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。<br>[https://dev.to/nwtgck/the-power-of-pure-http-screen-share-real-time-messaging-ssh-and-vnc-5ghc](https://dev.to/nwtgck/the-power-of-pure-http-screen-share-real-time-messaging-ssh-and-vnc-5ghc)