のらねこの気まま暮らし

技術系だけど、Qiita向きではないポエムとかを書くめったに更新されないヤツ

MojoでWebSocketするときのまとめ

Mojolicious::LiteでWebSocketを使うまでにやったいろんなこと。

あるていど落ち着いてきたのでさらっとまとめてみる。

  • Mojo側でやること
  • Client側でやること
  • Varnishの設定を変える必要がある
  • Androidでは対応ブラウザが少ない
  • SoftBankは80番ポート以外かWifiでつなぎましょう

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

現状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