LoginSignup
7
7

More than 5 years have passed since last update.

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

Posted at

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

Mojolicious::Lite で WebSocket を使ったチャットを作る - naoyaのはてなダイアリー

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

修正後

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が無い

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);をお忘れなく。

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

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

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7