NodeConf EU 2019でのトークの要点まとめです。
はじめに
- NearForm社でリサーチやってます
 - 主にOSS活動
 - 最近はNodeにQUICを実装してる
 
HTTP/2 in Node.js
- その前にHTTP/2について
 - Nodeにも実装はあって、2017年にコアにはいった
- けど、残念ながら使い勝手はあまりよくない...
 
 - だいたいのNodeは前段にNginxなどを置くせい
 - HTTP/2はステートフルなプロトコル
- ヘッダ圧縮のために、コネクションは状態を持つ必要がある
 - それを経由するミドルボックスで協調してメンテするのが無理
 
 - Node <-> Nodeとか、ブラウザ直でつなげるなら有用ともいえる
 
HTTP/2
- HTTP/1.xは、1リクエスト:1TCPコネクション
 - なのでHOLBが問題になる
- 1つパケットが落ちると、後続のパケットはその再送を待つ
 
 - HTTP/2では、リクエストを多重化した
- Nリクエスト:1TCPコネクション
 
 - しかし結局TCPなので、HOLBからは逃れられない...
 - 物理的に距離が遠かったり、モバイルなど低品質のNWの場合にそれが顕著
 
QUIC
- そこでQUIC, HTTP/3
 - QUICはUDPベース
- unreliableなプロトコル
 - それぞれのパケットは独立してる
 
 - なのでTCPでやってたことを、全部実装しなおしてる
- 到達確認(=reliable)
 - シーケンス(=ordering)
 - 輻輳制御
 - 暗号化 w/ TLS1.3
 - etc...
 
 - HTTP/3は、そんなQUICセッションを束ねてる
 - TCPはIPに紐付いたコネクションなので、NWを変えると切れる
- そういうのも大丈夫
 
 
QUIC in Node.js
const { createSocket } = require("quic"); const socket = createSocket(); socket.listen({ port: 443, key, cert, ca }); socket.on("session", session => { session.on("stream", stream => { stream.end("Hello world!"); }); });
- ただいま絶賛実装中
 - という具合に、見慣れたNodeのコードで書ける
- `stream`は単なる`Duplex`な`Stream`
 
 - そしてQUICは単なるトランスポートプロトコル
 
const { createSocket } = require("quic"); const socket = createSocket(); const req = socket.connect({ address, port: 443, key, cert, ca }); req.on("secure", () => { const stream = req.openStream(); stream.end("Hello world!"); stream.on("data", data => {}); });
- という感じでHTTP/3を実装する
- QUIC上のアプリケーションプロトコルとして
 
 - なのでQUICの上に独自のプロトコルを実装することもできる
 
進捗
- `ngtcp2`の`tatsuhiro-t`さんありがとう
 - 実装はここで進行中
 - おそらく2019年の11月末にExperimentalなPRをコアに出せそう
- ただし来年いっぱいくらいはAPIを洗練したり検討したりすると思う
 - まだ実装しないといけないこともいっぱいあるし
 
 - (クラサバでパケットを送り合うデモ)
- 流れたByte数とかストリームの数などが、JSのAPIから取れる!
 
 - Wiresharkとかでデバッグできるようキーロギングサポートも