WEBサイトの製作、管理、とかの日記ブログです。

<<   2023年06月   >>
SunMonTueWedThuFriSat
    123
45678910
11121314151617
18192021222324
252627282930 
新着記事
カテゴリ
過去ログ
コメント
検索
MojoliciousでWebSocketその2
その2では、まずエコーサーバー作ろうかと思ったが、
大して難易度変わらんと思うので、やっぱりチャットにした。

ws3.pl
#!/usr/bin/perl

use Mojolicious::Lite;
our(%CLIENT);
websocket '/' => sub{
    my $self=shift;
    $self->on(message => sub{
        my $tx=shift;
        my($cmd,$mes)=split(/,/,shift,2);
        if($cmd eq '1'){
            $CLIENT{$tx}=$tx;
            print "logon:".$tx."\n";
        }elsif($cmd eq '3'){
            if($mes=~/^[\w\%\-\.\~\!\*\'\(\)]+$/){
                print "message: $mes\n";
                foreach my $c(keys(%CLIENT)){
                    $CLIENT{$c}->send_message($mes);
                }
            }
        }
    });
};
app->start;

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
var WS=new WebSocket("ws://127.0.0.1:3000/");
WS.onopen=function(){
    WS.send('1');
};
WS.onmessage=function(e){
    document.getElementById('chat').value+=decodeURIComponent(e.data)+"\n";
};
function SendMessage(text){
    WS.send('3,'+encodeURIComponent(text));
}
</script>
<input id="text"><button onclick="SendMessage(document.getElementById('text').value);document.getElementById('text').value=''">送信</button>
<div><textarea id="chat" style="width:640px;height:480px"></textarea></div>
</body>
</html>

Mojolicious::Lite
を利用すると、strictとwarningsになっちゃうんで、
変数を利用する前に宣言が必要になる。
Perlの利点損なうから、strictとwarnings嫌いなんだがな・・・

手元のMojoliciousはUbuntu 12.04の2系列なんだが、CPANの方は3系列。
多分バージョンの違いと思うんだが、
CPANのMojolicious説明ではサーバーからクライアントへの送信に send を使ってるんだが、機能しなかった。
他所のMojoliciousサンプル見ると、sendではなくsend_message使って送信してたんで試したら送信できた。
あと、Mojo::Transactionにconnectionメソッドがあって、それで接続識別IDが取得できそうなんだが、無理だった。
接続のリファレンスを識別IDにしてハッシュに入れて、受信時に全端末に送信する感じにした。

connectionイベントってのもあるんで、接続開始時に発行されるもんだと思うんだが、
これも機能しなかったんで、ログオン用のメッセージを最初に送って、端末登録はメッセージ受信時にすることにした。
ちゃんとしたチャット作るなら名前の送信もあるから、どっちにしろアプリでログオン用のメッセージ送信するべきではあるかもね。


クライアントの方は、<textarea>に追加していくだけ。
受信はonmessageイベントで取れる。
onmessageイベントに登録する関数には引数としてeventが渡され、event.dataに受信テキストが入ってる。
送受信する文字列はURLエンコードするようにした。


今回の実験で、バージョン3系列と2系列の違いっぽいのが確認できたんで、
本格的に使うのはUbuntuのリポジトリとCPANのバージョンが同じになってからにしたいな・・・
まあ、CPANはしたくないんで、現状で使うなら2系列かなあ・・・
この記事へのコメント
名前:
URL
コメント:
この記事へのトラックバック :
whblog 1.7