Plack::App::WebSocketとAnyEvent::WebSocket::Serverをリリース
PSGIアプリケーション上でお手軽にWebSocketを使うためのモジュールPlack::App::WebSocketをリリースしました。
こんな感じで使います。
builder { mount "/websocket" => Plack::App::WebSocket->new( on_establish => sub { my ($conn) = @_; ## Plack::App::WebSocket::Connection object $conn->on( message => sub { my ($conn, $msg) = @_; $conn->send($msg); }, finish => sub { undef $conn; warn "Bye!!\n"; }, ); } )->to_app; mount "/" => $your_app; };
AnyEventを使っているので、TwiggyのようなAnyEvent対応型PSGIサーバと組み合わせて使うようにしてください。
また、PSGIと無関係にstand-aloneのWebSocketサーバを立てるためのモジュールAnyEvent::WebSocket::Serverもリリースしています。
個人的にはこっちの方がオススメです。
なぜ作ったのか?
「AnyEvent + PSGIベースのWebSocketサーバ実装」がCPAN上に存在しなかったからです。
WebSocketを用いた高レベルな通信モジュールなら存在します。
- https://metacpan.org/pod/PocketIO
- https://metacpan.org/pod/SockJS
- https://metacpan.org/pod/Web::Hippie
Webサーバ - ブラウザ間通信をきちんとやるならこうしたモジュールを使った方がよいでしょう。ただ、「ちょっとWebSocketで遊びたい」くらいの場合はなんかオーバースペックに思えます。あと、この手の上位プロトコルって、クライアントが非ブラウザな場合でもお手軽に使えるんでしたっけ?
特定のWeb application frameworkに依存したWebSocket実装なら存在します。
- https://metacpan.org/pod/Mojo::Transaction::WebSocket
- https://metacpan.org/pod/Amon2::Plugin::Web::WebSocket
もちろんこれらの実装は他のWAFでは使えません。
非AnyEventなWebSocketサーバ実装なら存在します。
Net::WebSocket::Serverは独自のイベントループを立てるのでAnyEvent非互換です。Net::Async::WebSocketはIO::Asyncベースなので一応AnyEventと一緒に使えるとは思います。
Github上にはいくつかAnyEventベースのWebSocketサーバ実装が存在します。
- https://github.com/motemen/Plack-Middleware-WebSocket
- https://github.com/apparentlymart/perl-anyevent-websocket
ただし、これらのモジュールはかなり古く、現在のWebSocketプロトコル(RFC 6455)には対応していません。
というわけで、意外とAnyEventなWebSocketサーバ実装ってなかったんですよね。もう世の中の人はWebSocketなんていう低レベルプロトコルはまともに使わないのだろうか。あるいはWebSocketの処理をPerlでやる人がそもそもいないのか。