5年前の動かなくなっていたWebSocketコードをなんとかする

”Mojolicious WebSocket”でggrと真っ先に検索トップに登場するコチラ

[Mojolicious::Lite で WebSocket を使ったチャットを作る - naoyaのはてなダイアリー](http://d.hatena.ne.jp/naoya/20101011/1286778922)

もう5年近く経っており、動かなくなっていたので動くようにする
（仕方ないんや…まだ仕様とかいろいろ決まってなかったんだから）

# 修正後

```pl:my_app.pl
#!/usr/bin/env perl
use utf8;
use Mojolicious::Lite;
use DateTime;
# use Mojo::JSON;
use Mojo::JSON qw(encode_json);

get '/' => 'index';

my $clients = {};

websocket '/echo' => sub {
    my $self = shift;

    # timeout 15s to off
    my $tx = $self->tx;
    Mojo::IOLoop->stream($tx->connection)->timeout(0);

    app->log->debug(sprintf 'Client connected: %s', $self->tx);
    my $id = sprintf "%s", $self->tx;
    $clients->{$id} = $self->tx;

    #$self->receive_message(
    $self->on(message => sub {
        my ($self, $msg) = @_;

        #my $json = Mojo::JSON->new;
        my $dt   = DateTime->now( time_zone => 'Asia/Tokyo');

        for (keys %$clients) {
            #$clients->{$_}->send(
            #    $json->encode({
            #        hms  => $dt->hms,
            #        text => $msg,
            #    })
            #);
            $clients->{$_}->send(
                encode_json {
                  hms  => $dt->hms,
                 text => $msg,
               }
            );
        }
    });

    #$self->finished(
    $self->on(finish => sub {
       app->log->debug('Client disconnected');
       delete $clients->{$id};
    });
};

app->start;

__DATA__
@@ index.html.ep
<html>
  <head>
    <title>WebSocket Client</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" ></script>
    <script type="text/javascript" src="/js/ws.js"></script>
    <style type="text/css">
      textarea {
          width: 40em;
          height:10em;
      }
    </style>
  </head>
<body>

<h1>Mojolicious + WebSocket</h1>

<p><input type="text" id="msg" /></p>
<textarea id="log" readonly></textarea>

</body>
</html>
```

# 解説

## 置き換え

receive_message, finishedは無くなりました。
``$self->on(message``, ``$self->on(finish``に置き換えです。

## Mojo::JSONにnewが無い

```txt
Mojo::Reactor::Poll: I/O watcher failed: Can't locate object method "new" via package "Mojo::JSON" at app.pl line 23, <DATA> line 70.
```

encode_jsonでエンコードします。
``use Mojo::JSON qw(encode_json);``をお忘れなく。

## タイムアウトを無制限にする

```pl
my $tx = $self->tx;
Mojo::IOLoop->stream($tx->connection)->timeout(0);
```

15秒デフォルトでセッションが切られてしまうので無制限にします。

# 参考

Mojolicious::Lite で WebSocket を使ったチャットを作る - naoyaのはてなダイアリー
http://d.hatena.ne.jp/naoya/20101011/1286778922

Mojolicious::Lite で WebSocket を使ったチャットを作る(現時点：2012年3月10日で動くコード) - 僕のYak Shavingは終わらない
http://kazuph.hateblo.jp/entry/20120310/1331396492

MojoでWebSocketするときのまとめ - のらねこの気まま暮らし
http://mizuki-r.hatenablog.com/entry/2012/02/25/101222
WebSocketのTimeout時間は300秒、らしい。
ほっとくとすぐTimeoutしちゃいます。
明確にこのTimeout時間を制御する方法がなかったりするので、とりあえず定期的にpingを送ってごまかそう

Mojolicious::Lite で WebSocketのタイムアウトの時間を修正する - 僕のYak Shavingは終わらない
http://kazuph.hateblo.jp/entry/20120310/1331395725

Mojo::IOLoop::Stream · yuki-kimoto/mojolicious-guides-japanese Wiki
https://github.com/yuki-kimoto/mojolicious-guides-japanese/wiki/Mojo::IOLoop::Stream
ストリームが自動的に閉じられる前に、ストリームが非アクティブになるまでの 最大の秒数。
デフォルトは15です。この値を0に設定すると、 このストリームが無期限に非アクティブでいることを許可します。

弁財天: Mojoliciousを暗号化WebSocket(wss://)で環境構築 update4
http://benzaiten.dyndns.org/roller/ugya/entry/mojolicious-websocket