📚

アカマイの方が提案する『WebブラウザにおけるIPマルチキャスト』について

2021/05/03に公開

背景

https://github.com/GrumpyOldTroll/wicg-multicast-receiver-api/blob/master/explainer.md

提案者はアカマイの方だそうです。
CDN業者にとって、人気のあるスポーツ中継やドラマなどをネットで配信することが大変だそうです。
当然のことながら、TV放送と違ってWebでの動画ストリーミングはクライアントの数だけトラフィックが増えます。
このままではヤバイ! インドのクリケット人気なめんなよ! ということで、IPマルチキャストをやっていこまいという提案がなされました
まだ提案だけです。

IPマルチキャスト

まず、IPマルチキャストについて簡単に説明します。
IPマルチキャスト自体は凄く昔からある規格(1986年らしい)です。
多分(想像だけど)、大学の構内LANなどで配布物を効率よく送りたかったのだと思います。
これまでWebで使われたことはありませんでしたが、それ以外の様々な用途で使われてきました。

モチベーション

同じネットワーク内に同じデータを要求している端末が複数台あった場合、
『一回の送信』『複数の端末』 が受信できるようにしたい、ということです。

無線LANであれば、電波は全ての端末に届いているので、
ルーターは「俺は一回しか発信しないから必要な人は各自受け取ってね〜」っていうだけですね。

有線LANの場合は、図のように共通の中継器まで一回送信し、
その後必要に応じて分岐していく感じになります。
注意点として、IPマルチキャストはIPレイヤーの仕様なので、Ethernetレイヤーのハブがどういう動きをするかはその機械によります。
ただし、少なくとも僕が知っている限り市販のハブは大体いい感じにしてくれます。

根本のLANケーブルが一回しかデータを送っていない点が特徴です。

動き

動きがわかるとだいたい何をしているのか想像がつくと思います。

まず、ここに二台のPCがあったとします。
それぞれ、IPは

  • Xパソコン:xxx.xxx.xxx.xxx
  • Yパソコン:yyy.yyy.yyy.yyy

だとします。
ここでXパソコンがルーターに対し、「IPマルチキャストグループアドレス(以下グループアドレス)を発行してくれ」と依頼します。
ルーターはggg.ggg.ggg.gggというグループアドレス発行し、Xパソコンに伝えます。
XパソコンはYパソコンに「お前もggg.ggg.ggg.gggに入ってこいよ」と言います。
それを聞いたYパソコンはルーターに「俺もggg.ggg.ggg.gggに入る」と言います。
ルーターはYパソコンをggg.ggg.ggg.gggに入れます。
すると、今後ggg.ggg.ggg.ggg宛のパケットはXパソコンにもYパソコンにも届くようになります。
『パソコンXとパソコンYがggg.ggg.ggg.gggに入った』という情報はネットワーク上の各種中継器にも伝わるようになっているので、
いい感じに中継を最適化してもらえます。

まあ、メーリングリストとかファイル共有サービスみたいなものでよくある仕組みと似たようなものです。

何に使えるのか

アカマイは、ISPをまたいでIPマルチキャストすることで超大規模なスポーツイベントなど効率よく配信したいのではないかと思います。
でも、あんまり僕達には馴染みがない話だと思います。

もう少し身近な用途があると思います。
例えば、オンラインミーティングで同じ会議に参加している人がLAN内に複数人居るケースってありますよね。
また、Droid会議のような大きなIT系のイベントだと
現場で発表を見つつネット配信も見てる人って結構いますね。

そういう時に、LAN内に居る人にはマルチキャストをして、外に居る人には普通に配信するようなことが出来ると思います。

どんなJSのAPIになるのか

基本的には、JSでストリームオブジェクトを作って、イベントストリームをListenしていく感じだと思います。
ストリームオブジェクトを作る時にグループアドレスを指定したりするようです。
提案では、こんな感じのコードでした。

// Multicast flow to join:

let multicastFlow = {
  source: '198.51.100.10',
  group: '232.10.10.1',
  port: 5001,
  dorms: 'dorms.example.com'
};
  
// Construct MulticastReceiver and subscribe to the multicast flow on the 
// network:

let multicastReceiver=new MulticastReceiver(multicastFlow);

// Read multicast UDP packets:

let multicastReader=multicastReceiver.readable.getReader();

async function readMulticastData() {
  for(;;) {
    let { done, value } = await multicastReader.read();
    if(done) {
      return;
    } else {
      // value is an UInt8Array with the payload of one UDP packet.
      console.log("Got multicast packet with size "+value.length);
    }
  }
}

暗号化や再送制御やネットワークの難しいあれこれはブラウザの中で抽象化するそうです。

まとめ

実現したら楽しそうですね。

Discussion