Javascript 通过AJAX更新网页字段的无限数据流?

Javascript 通过AJAX更新网页字段的无限数据流?,javascript,ajax,perl,Javascript,Ajax,Perl,注:这是我在这里的第一个问题 问题的简短版本: 如果我运行的服务器端脚本可以输出数据(实时传感器读数的值变化非常快),那么使用AJAX重复请求最新的脚本输出更合适,还是让脚本以无休止的流输出数据并使用AJAX读取、解析、,并在数据流流过时输出数据?第二个选项是否可行,或者AJAX是否在处理任何内容之前预期某种文件结束标志 问题的很长版本: 我正在构建一台由Arduino(读取传感器)、Raspberry Pi和10英寸LCD组成的车内计算机。我正在通过串行通信将数据从Arduino传输到Rasp

注:这是我在这里的第一个问题

问题的简短版本:

如果我运行的服务器端脚本可以输出数据(实时传感器读数的值变化非常快),那么使用AJAX重复请求最新的脚本输出更合适,还是让脚本以无休止的流输出数据并使用AJAX读取、解析、,并在数据流流过时输出数据?第二个选项是否可行,或者AJAX是否在处理任何内容之前预期某种文件结束标志

问题的很长版本:

我正在构建一台由Arduino(读取传感器)、Raspberry Pi和10英寸LCD组成的车内计算机。我正在通过串行通信将数据从Arduino传输到Raspberry Pi,格式如下:

output-timestamp: value1, value2, value3, value4, value5, etc.
使用Chrome/Chrome extensions,我可以将串行数据直接读取到浏览器中,从而实时显示传感器值。使用HTML5,我可以通过旋转图像层直观地显示串行数据,模拟典型汽车仪表盘中的各种仪表

但是,在Raspberry Pi上运行raspian时,可用的Chromium版本不支持HTML5。我可以重新编写动画,或者创建跨浏览器解决方案。我决定使用后者,尽管我是唯一一个使用它的人

在Raspberry上,我编写了一个perl脚本,它捕获串行数据并在运行时输出。我可以调整代码以编写一行数据:

output-timestamp: value1, value2, value3, value4, value5, etc.
或者我可以将其写入无休止的流:

output-timestamp: value1, value2, value3, value4, value5, etc.
output-timestamp: value1, value2, value3, value4, value5, etc.
output-timestamp: value1, value2, value3, value4, value5, etc.
etc., etc.
如果我要运行一个AJAX调用来获取数据,那么让perl脚本输出一次数据,然后让AJAX以非常快的速度一次又一次地请求最新版本的脚本,是更合适的做法,还是让perl脚本无休止地流式传输传感器数据,并使用AJAX在流式传输时读取、解析和显示数据?第二个选项是否可行,或者AJAX是否在开始处理之前等待某种文件结束标志


无论采用哪种方式,更新都需要非常快速地进行;我正在提取RPM、加速度计信号、速度计信号等,因此我们正在研究显示器的快速更新。

有各种框架可以帮助您通过http/json接口进行实时通信

具有出色的WebSocket支持,并且能够以您想要的方式传输数据

在较旧的浏览器中,添加一个垫片,根据需要将WebSocket优雅地降级为轮询机制

下面是一个使用Mojolicious::Lite的echo服务器示例,它是Mojolicious上相同包的一部分,但具有更简单的api

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => 'index';

websocket '/echo' => sub {
    my $self = shift;
    $self->on(message => sub {
            my ($self, $msg) = @_;
            my ($s,$m,$h) = localtime(time);
            $self->send({ json => { text => $msg, time=> "$h:$m:$s" }});
        });
};

app->start;

__DATA__
@@ index.html.ep
<html>
  <head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" ></script>
    <script type="text/javascript" charset="utf-8">
      $(function () {
          var log = function (text) { $('#log').val( $('#log').val() + text + "\n"); };

          var ws = new WebSocket('ws://localhost:3000/echo');
          ws.onopen = function () { log('Connection opened'); };

          ws.onmessage = function (msg) {
            var res = JSON.parse(msg.data);
            log(res.time + '> '  + res.text); 
          };

         $('#msg').keydown(function (e) {
             if (e.keyCode == 13 && $('#msg').val()) {
                 ws.send($('#msg').val());
                 $('#msg').val('');
             }
           });
         });
    </script>
  </head>
<body>
    <input type="text" id="msg" placeholder="Type Your Message Here" /><br>
    <textarea id="log" readonly></textarea>
</body>
</html>
!/usr/bin/env perl
使用mojolicous::Lite;
获取“/”=>“索引”;
websocket'/echo'=>sub{
我的$self=shift;
$self->on(消息=>sub{
我的($self,$msg)=@;
my($s,$m,$h)=本地时间(time);
$self->send({json=>{text=>$msg,time=>“$h:$m:$s”});
});
};
应用程序->启动;
__资料__
@@index.html.ep
$(函数(){
var log=函数(text){$('#log').val($('#log').val()+text+“\n”);};
var ws=newwebsocket('ws://localhost:3000/echo');
ws.onopen=function(){log('Connection opened');};
ws.onmessage=函数(msg){
var res=JSON.parse(msg.data);
日志(res.time+'>'+res.text);
};
$('#msg').keydown(函数(e){
如果(e.keyCode==13&&$('#msg').val()){
ws.send($('#msg').val());
$('#msg').val('');
}
});
});

您可以使用
perl app.pl守护进程启动此程序,并将其托管在各种http服务器(如apache)上

当你开始这个你应该看到


请注意时间戳是如何添加到服务器端的,以及完整的消息是如何发送回来的。

非常感谢您,harvey。在我阅读代码并对其进行修改的过程中,我试图准确地理解它是如何工作的。由于我试图以某种方式使数据流流动,因此似乎唯一可行的方法是使用javascript端口代码的初始化会对服务器进行多次调用。这里的这一部分,例如:ws.send($('#msg').val();您可以很容易地扩展这个示例,添加一个全局变量
my@connections=();
。创建一个新的websocket端点,例如
websocket'/stream=>sub{my$self=shift;push@connections,$self}“
。现在您可以将数据流传输到客户端,而无需进行轮询,例如使用
foreach my$c(@connections){$c->send({text=>'Hello';})sleep 2;};
。这样,您就可以向所有客户端发送恒定的数据流,在客户端断开连接时不要忘记删除连接。有关详细信息,请参阅(此)[。