SSE を1から実装してチャットを作りました。
コードは GitHub で公開しています。
どんな動きをするかは動画で
https://youtu.be/x_GVnE-pa-s
動機
リアルタイム通信したい
対戦ゲームとかそういうの作れるようになっておきたい
素振り
Sinatra のような薄いフレームワーク(FW)を使い、大部分を自分でコントロールしたい
会社のとあるプロジェクトでDBのシャーディングをしたが、Rails では対応しておらず苦労した
フルスタックなFWだとコードを見るのも大変。
フルスタック出なければ対応しているライブラリを使えばいいだけ(Sequel など)
よかったこと
SSE の規格を読んで、サーバー側の実装を1からできたこと。
規格が短めで実装も簡単なので、初めてやるのにちょうど良かったと思います。
クライアントからの切断を検知する機能を作った。
SSE の規格としては存在しない機能
TCP ソケットを監視することで検知
これによってクライアントが存在しないゾンビストリームを防止できた。
APIサーバーをスケール可能にできた。
Redis の PubSub を使うことでユーザー同士のやり取りを繋いでいるため、APIサーバーが複数でも大丈夫
並行処理をうまく書けた。
以下の3つを並行処理するが、それを利用者側に意識させない作りができた。
KeepAlive用のタイマー処理
クライアント切断の監視処理
実際のSSEの処理
Sinatra を使えるようになった
FWに振り回されるのではなく、自分がコントロールできている部分が大きくなった
SSE、TCPソケット、並行処理などなど
Docker を使って環境をコード化し、どこでも再現できること
React と Parcel もいい味を出している
設計判断
WebSocket ではなく Server Sent Events にした理由
実装と仕組みが簡単で、自分でコントロールしやすい
再接続などが規格で整備されている
HTTP の延長上にある
(WebSocket を突き詰めていくとルーティングやヘッダーなどhttpを再実装するようなことになるらしい?)
それらを処理しないことによる速さを活かす場合もあるので何とも言い難い
既存の Sinatra の SSE ライブラリを使わない理由
Puma サーバーに対応してない
クライアントの切断を検知できない
殴り書き
サービスとしては面白みが少ないので、サーバー代払ってまでデモを用意したくなかった。
代わりに動画を用意したいが撮るのが億劫
撮りました……!
書きながら思ったけど heroku 使うといいのか?