问题描述
注意:这是我在这里的第一个问题。
问题的简短版本:
如果我正在运行一个可以输出数据的服务器端脚本(实时传感器读数的值变化非常快),使用 AJAX 重复请求最新的脚本输出更合适,还是更合适?让脚本在无限流中输出数据,并在数据流过时使用 AJAX 读取、解析和输出该数据? 第二个选项甚至可能吗,或者 AJAX 在处理任何事情之前是否预期某种文件结束标志?
问题的很长版本:
我正在构建由 Arduino(读取传感器)和 Raspberry Pi 和 10" LCD 组成的车载计算机。我正在通过串行通信将数据从 Arduino 流式传输到 Raspberry Pi,格式如下:
output-timestamp: value1, value2, value3, value4, value5, etc.
使用 Chrome/Chromium 扩展程序,我可以将串行数据直接读入浏览器,从而实时显示传感器值。 使用 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、加速度计信号、速度计信号等,所以我们正在查看显示的非常快速的更新。
1楼
harvey
1
2015-07-31 01:55:22
有多种框架可以帮助您通过 http/json 接口进行实时通信。
具有出色的 Websockets 支持,并且能够以您想要的方式传输数据。
在较旧的浏览器中,添加一个垫片,它将根据需要优雅地将 websocket 降级为轮询机制。
这是一个使用 Mojolicious::Lite 的回显服务器示例,它是 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>
您可以使用perl app.pl daemon
启动该程序,也可以将其托管在各种 http 服务器(例如 apache)上。
当你开始这个时,你应该看到;
注意时间戳是如何在服务器端添加的,以及完整的消息是如何发回的。