2017-04-01 108 views
4

我是新来的网络套接字,并且围绕与IoT设备交谈的命令行界面构建一个Web GUI。有些命令需要几秒钟才能运行,因为我将它们发送到大型设备网络。我可以通过Web套接字动态更新HTML吗?

这将是非常有益的,如果我能通过单个设备响应一个textarea(类似一个终端窗口)作为响应进来。

我使用的客户端和服务器之间的网络套接字连接。这里是我试图达到的效果的一个简化例子。

#!/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> 

在这个例子中,我有一个循环计数从0到14,我要发送的每个算到textarea的通过网络插座显示器作为循环计数。该循环在我的实际应用程序中模拟CLI响应。这甚至有可能通过网络套接字来完成?

CNC中

修改上述网络套接字代码,并使用Mojo::IOLoop->recurring解决问题,而不必诉诸于多线程。

websocket '/get_loop' => sub { 

    my $c = shift; 

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

    my $id; 
    $c->on(message => sub { 

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

     my $count = 0; 
     $id = Mojo::IOLoop->recurring(1 => sub { 
      $c->send("$count\n"); 
      $c->app->log->debug($count); 
      sleep (1); 
      $c->finish if $count++ == 10; 
     }); 
    }); 

    $c->on(finish => sub { 
     my ($c, $code, $reason) = @_; 
     Mojo::IOLoop->remove($id); 
     $c->app->log->debug("WebSocket closed with status $code"); 
    }); 
}; 
+2

是的,你可以做到这一点...你应该这样做?你是如何做到的?这些都是项目相关的具体细节...可能传递原始数据与websocket和格式化发生在客户端,或从服务器传递解析的HTML到客户端...(我会做A)...有很多不同的如何做到这一点。 – Myst

+0

我提供的示例显示我通过Web套接字将数据从服务器传递到客户端。问题在于,服务器上的个人“计数”在服务器从零开始计数时不会实时显示在textarea上。相反,服务器在循环完成后吐出所有的东西。我应该在我的问题中更清楚地说明这一点。我毫无困难地将数据传递给Web套接字,我无法弄清楚在服务器处于循环状态时如何实时发送数据。 – MySilmaril

+0

您显示的代码是否存在特定问题,需要帮助? – jfriend00

回答

0

您需要在页面上的JavaScript的WebSocket监听器,并插入传递到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中创建一个静态的连接数组,将它们分配给打开的事件,并在关闭事件时取消分配它们。您不需要在on消息子文件中发回数据。您可以使用Event :: Lib $ event-> add([$ timeout]),然后枚举调用$ c-> send(“$ i \ n”)的打开套接字(对各种不同的Web客户机)。它完全是异步的,所以不需要将它与on消息子节点绑定。服务器可以随时做到。

使静态变量PERL: http://www.perlmonks.org/?node_id=8299

相关问题