MojoでWebSocketするときのまとめ
Mojolicious::LiteでWebSocketを使うまでにやったいろんなこと。
あるていど落ち着いてきたのでさらっとまとめてみる。
Mojo側でやること
webscoketメソッドを使って、websocket通信を受け付けるURLを用意。
各種イベントに対する動作を設定する。
$self->onの第1引数にイベント、第2引数に動作をサブルーチンリファレンスで渡せばいい。
$self->on(message => sub {...}); $self->on(finish => sub {...});
テスト段階での実装はとりあえずこんな感じ。
my $clients = {}; websocket '/websocket/:rid' => {rid => undef}, sub { my $self = shift; $self->app->log->debug('socket open'); my $id = sprintf "%s", $self->tx; my $rid = $self->param('rid'); $clients->{$rid}{$id} = $self->tx; $self->on(message => sub { my ($self, $msg) = @_; $self->app->log->debug($msg); #my $json = Mojo::JSON->new->encode($msg); for (keys %{$clients->{$rid}}) { $clients->{$rid}{$_}->send_message($msg); } }); $self->on(finish => sub { my $self = shift; $self->app->log->debug('WebSocket closed'); }); };
client側でやること
WebSocketのインスタンスを作成すると、引数にしていしたURLに対してWebSocketのコネクションを貼ってくれる。
var ws = new WebSocket("ws://"+location.host+"/websocket/"+rid);
各イベントに挙動を設定する
// socket open時の処理 ws.onopen = function(){ ... }; // messageを受信した際の処理 ws.onmessage = function(msg){ ... }; // 通信終了時・切断時の処理 ws.onclose = function(){...}; // ボタンをおしたらメッセージ送信 $("#btn").click(function(){... ws.send(message); };
Varnishの設定を変える必要がある
詳細は以前書いた記事にて
http://mizuki-r.hatenablog.com/entry/2012/02/18/212913
要するに、VarnishはWebSocketと断定とするのに必要なHeaderを途中でそぎ落としちゃうので、ちゃんとバックエンドに届けるようにしましょうね。という話。
Androidでは対応ブラウザが少ない
僕が使っているAndroidBlowser
- Blowser
- Dolphin Blowser
- Firefox
現状WebSocketが実装されているのは
らしい。とりあえずFirefoxで動くのでまあいいやということでOperaは試していないのねん。
また、Firefoxで動作させるためには、WebSocketではなく、MozWebSocketを使う必要がある。
Firefox11でWebSocketで使えるようになるという噂があるけれど、いまはまだ10なので、Firefoxで動かしたければMozWebSocketを使いましょう。
var socket; if (typeof WebSocket != 'undefined') socket = new WebSocket(ws); else if (typeof MozWebSocket != 'undefined') socket = new MozWebSocket(ws); else { alert('WebSocket非対応です'); return false; }
SoftBankは80番ポート以外か無線LANでつなぎましょう
これも過去の記事にて。
http://mizuki-r.hatenablog.com/entry/2012/02/25/094947
SoftBankのSmartphoneは3Gじゃなくて無線LANで接続するか、Websocketの通信には80番ポート以外を使いましょうというお話です。
WebSocketのTimeout時間は300秒、らしい。
ほっとくとすぐTimeoutしちゃいます。
明確にこのTimeout時間を制御する方法がなかったりするので、とりあえず定期的にpingを送ってごまかそう
var connection_interval = setInterval(function(){socket.send('ping')}, 200000);
おわりに
とりあえずGitHubにあげときやした。
https://github.com/rymizuki/SlidePlus/tree/websocket