我有这个代码片段,我试图每X秒将一个字符串推送到服务器,如:
#!/usr/bin/env perl use MojolicIoUs::Lite; use EV; use AnyEvent; use POSIX qw(strftime); get '/' => sub { my $self = shift; $self->render('main'); }; websocket '/echo' => sub { my $self = shift; my $w; $w = AE::timer 3,1,sub { $self->send('Got it'); }; # $self->send(strftime("Server $$: %a %b %e %H:%M:%S %Y",localtime)); }; app->start(); __DATA__ @@ main.html.ep <html> <head> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> </head> <body> <table id="tableID"> <tbody> </tbody> </table> <script type="text/javascript"> var ws = new WebSocket('ws://192.168.1.104:3000/echo'); ws.onopen = function () { alert('Connection opened'); }; ws.onerror = function() { alert("Error"); }; ws.onmessage = function (msg) { $("#tableID").find('tbody') .append($('<tr>') .append($('<td>') .text(msg.data) ) ); }; </script> </body> </html>
AFAIK Mojo使用IO :: Loop事件循环,我认为AnyEvent应该没问题
这不起作用,我想知道为什么.
当我删除AE部分并取消注释简单发送时,我在浏览器中看到结果.
P.S:只是试验一些项目的WebSockets和Mojo我将需要使用Both Mojo和AnyEvent WebSockets
解决方法
问题似乎是在GET连接升级到websocket之前发送消息正在尝试发生.我仍然试图追踪它,与此同时这是有效的.
#!/usr/bin/env perl use MojolicIoUs::Lite; use EV; use AnyEvent; #use POSIX qw(strftime); get '/' => sub { my $self = shift; $self->render('main'); }; websocket '/echo' => sub { my $self = shift; my $w; $self->on(finish => sub { Mojo::IOLoop->remove($w) }); # $self->send(strftime("Server $$: %a %b %e %H:%M:%S %Y",localtime)); $w = Mojo::IOLoop->recurring( 1 => sub{ $self->send('Got it'); }); }; app->start(); __DATA__ @@ main.html.ep <html> <head> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> </head> <body> <table id="tableID"> <tbody> </tbody> </table> <script type="text/javascript"> var ws = new WebSocket("<%= url_for('echo')->to_abs %>"); ws.onopen = function () { alert('Connection opened'); }; ws.onerror = function() { alert("Error"); }; ws.onmessage = function (msg) { $("#tableID").find('tbody') .append($('<tr>') .append($('<td>') .text(msg.data) ) ); }; </script> </body> </html>
请注意,在我的示例中,调试输出显示101个切换协议,而您的示例尝试自动调试echo.html.ep.
我还更改了模板以生成websocket url.
更新:
似乎为了连接到websocket,它必须订阅一个事件.在这个例子中,我订阅了完成事件,你想要做的就是停止计时器.
#!/usr/bin/env perl use MojolicIoUs::Lite; use EV; use AnyEvent; #use POSIX qw(strftime); get '/' => sub { my $self = shift; $self->render('main'); }; websocket '/echo' => sub { my $self = shift; my $w; $w = AE::timer 3,sub { $self->send('Got it'); }; $self->on(finish => sub{ undef $w }); # $self->send(L<MojolicIoUs::Controller/strftime("Server $$: %a %b %e %H:%M:%S %Y",localtime)); }; app->start();
更新2:
为了澄清问题,SRI有added the following documentation to Mojolicious:
The connection gets established when you respond to the WebSocket handshake with a 101 response status,which happens automatically if you subscribe to an event with
“on” or send a message with “send” right away.