Perl 我可以通过Web套接字动态更新HTML吗?

Perl 我可以通过Web套接字动态更新HTML吗?,perl,websocket,Perl,Websocket,我不熟悉web套接字,我正在围绕与物联网设备对话的命令行界面构建web GUI。有些命令需要几秒钟才能运行,因为我正在将它们发送到一个大型设备网络 如果我能在收到响应时将单个设备的响应传递到文本区域(类似于终端窗口),那将非常有帮助 我正在客户端和服务器之间使用web套接字连接。下面是一个我试图达到的效果的简化示例 #!/usr/bin/env perl use strict; use warnings; use Mojolicious::Lite; get '/' => 'index

我不熟悉web套接字,我正在围绕与物联网设备对话的命令行界面构建web GUI。有些命令需要几秒钟才能运行,因为我正在将它们发送到一个大型设备网络

如果我能在收到响应时将单个设备的响应传递到文本区域(类似于终端窗口),那将非常有帮助

我正在客户端和服务器之间使用web套接字连接。下面是一个我试图达到的效果的简化示例

#!/usr/bin/env perl

use strict;
use warnings;
use Mojolicious::Lite;

get '/' => 'index';

websocket '/get_loop' => sub {

    my $c = shift;

    $c->app->log->debug("Websocket opened");

    $c->on(message => sub {

        my ($c, $msg) = @_;

        for (my $i = 0; $i < 10; $i++) {
            $c->send("$i\n");
            $c->app->log->debug("$i\n");
            sleep (1);
        };
    });

    $c->on(finish => sub {
        my ($c, $code, $reason) = @_;
        $c->app->log->debug("WebSocket closed with status $code");
    });
};

app->start;

__DATA__

@@ index.html.ep
<html>
<head>
    <title>Websocket Test</title>
    <style type="text/css">
        textarea {
            height: 200px;
            width: 100px;
        }
    </style>
</head>
<body>
    <h1>Websocket Test</h1>
    <textarea id="terminal" readonly></textarea>
    <script type="text/javascript">
        var ws = new WebSocket('ws://127.0.0.1:3000/get_loop');
        var terminal = document.getElementById('terminal');
        ws.onopen = function() {
            ws.send('start');
        };
        ws.onmessage = function(event) {
            var msg = event.data;
            terminal.innerHTML += msg;
        };
    </script>
</body>
</html>

您需要在页面上创建JavaScriptWebSocket侦听器,并插入传递到DOM中的数据

const socket = new WebSocket('ws://localhost:8080');
socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

socket.addEventListener('message', function (event) {
    var div = document.getElementById('divID');
    div.innerHTML = event.data;
});
哦,我明白了,你的问题是关于服务器Perl代码的。我建议在Perl中创建一个静态连接数组,在open事件中分配它们,在close事件中取消分配它们。您不需要将数据发送回on message sub。您可以使用Event::Lib$Event->add([$timeout]),然后通过调用$c->send(“$i\n”)、打开的套接字进行枚举(到各种不同的web客户端);它是完全异步的,因此不需要将其与on消息子节点绑定。服务器可以在任何时候执行它

在PERL中生成静态变量:

是的,你可以做到。。。你应该这样做吗?你是怎么做到的?这些是与项目相关的细节。。。可能通过websocket传递原始数据并在客户端进行格式化,或者从服务器向客户端传递解析后的HTML。。。(我会做一个)。。。有许多不同的方法可以做到这一点。我提供的示例显示,我正在通过web套接字将数据从服务器传递到客户端。问题是,当服务器从零开始计数时,来自服务器的单个“计数”不会在文本区域中实时显示。相反,服务器会在循环完成后吐出所有内容。我应该在我的问题中更清楚地说明这一点。我在web套接字之间传递数据没有问题,我只是不知道如何在服务器处于循环中时实时发送数据。您显示的代码是否存在需要帮助的特定问题?这是因为javascript是均匀的和单线程的-这意味着
send
调度一个事件,直到您的代码退出循环后才会处理该事件。只要代码在运行,就不会处理其他事件。我正在简化解释,但经验法则是“假设在代码返回之前什么都没有发生”。另外,哦,糟糕,我没有注意到服务器在
perl
,但是,同样的规则可能适用于…?删除
for
循环,并用
my$id=Mojo::IOLoop->recurrential(1=>sub{…})替换它,并将循环中的内容放入子循环中(可删除的
睡眠
除外)。
const socket = new WebSocket('ws://localhost:8080');
socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

socket.addEventListener('message', function (event) {
    var div = document.getElementById('divID');
    div.innerHTML = event.data;
});