Javascript 将Python脚本的状态流式传输到网站

Javascript 将Python脚本的状态流式传输到网站,javascript,python,streaming,real-time,Javascript,Python,Streaming,Real Time,我有一个简单的工作流[Step 0]->[1]->[2]->…->[Step N]。主程序知道其当前所处的步骤(状态) 我想将其实时传输到一个网站(在局域网中),这样当我的同事打开时,比如说,http://thecomputer:8000,他们可以看到实时呈现的工作流当前状态以及任何相关细节 我曾经考虑过将脚本的状态写入StringIO对象(流式传输到它),并使用Javascript刷新浏览器,但我真的不知道如何真正做到这一点 有什么建议吗?您可以让python脚本编写一个xml文件,通过aja

我有一个简单的工作流
[Step 0]->[1]->[2]->…->[Step N]
。主程序知道其当前所处的步骤(状态)

我想将其实时传输到一个网站(在局域网中),这样当我的同事打开时,比如说,
http://thecomputer:8000
,他们可以看到实时呈现的工作流当前状态以及任何相关细节

我曾经考虑过将脚本的状态写入
StringIO
对象(流式传输到它),并使用
Javascript
刷新浏览器,但我真的不知道如何真正做到这一点


有什么建议吗?

您可以让python脚本编写一个xml文件,通过ajax请求在您的网页中获取该文件,并从中获取状态信息。

如果您只是想快速解决问题,而不是完整的网页,签出您可以将您的状态信息以文件的形式写入目录,并将其更新,以供其他人查看

不漂亮,但是很快很容易

对于演示,只需键入
python-msimplehttpserver
这将创建一个地址为
http://[您的计算机名称或IP]:8000的网页,其中包含启动时所在的当前工作目录的内容。这些文件是热链接的。如果单击某个文件,它将显示在浏览器中;如果您单击一个目录,您将更改为该目录,并列出其内容

为了便于使用,您可以从一个空目录开始,创建与要报告的步骤相匹配的文件。您可以将文件命名为步骤,例如“step 1.txt”,并在该文件中包含更详细的信息。步骤1可以是脚本在步骤1完成时创建的目录,等等

或者,也可以签出,这将允许您直接从Python脚本提供HTTP请求


如果/当你想变得更时尚,你可以使用基本相同的方法。从python脚本将输出写入空目录中的文件。从使用PHP的web服务器上,编写一个简单的脚本,检查该目录并显示找到的内容。将页面上的刷新间隔设置为某个值,它将在浏览器中自动更新。

我不知道Python是如何工作的,但如果是PHP,这将很容易(如果您知道应该做什么)

假设我的应用程序是myapp.py,它从步骤1运行到步骤N。我会让它返回(简单文本),一个数字。此编号是its的“步骤编号”。例如,如果我调用,它将返回5。30分钟后,我重新加载页面,它返回15

现在来看JavaScript。我将推荐使用jQuery。它使事情变得更容易、更快。我所要做的就是

$('#streaming').load('http://localhost/myapp.py');
这将把页面内容加载到ID为streaming的DIV中。但只有在加载页面时才会发生这种情况。要使其每x秒发生一次,请使用JavaScript settimeout函数

var t=setTimeout("javascript statement",milliseconds);

最好将加载步骤的部分存储在函数中,并在页面加载时使用setTimeout调用它。一旦脚本停止工作(使用特殊的数字/消息),停止setTimeout也会有帮助。

使用普通JavaScript,您可以选择Comet、WebSockets和Ajax。然而,我对这些都不太了解。请访问以下网站:


据我所知,Comet只涉及向web服务器发出一个长期的Ajax请求,脚本可以在需要时推送数据。WebSocket仅在某些浏览器的最新版本中受支持。最简单的解决方案是Omar Abid建议的:每隔一段时间通过Ajax轮询web服务器一次。

您可以向应用程序添加一个服务器实例,以响应给定端口上的查询,无论应用程序决定共享什么。在访问应用程序状态信息的单独线程中启动此功能,然后让您的网页或监控程序向该端口发送请求。当然,您可以用不同的方式响应不同的请求。您需要的所有信息都已打开,但下面的代码将帮助您开始:

# borrowed from https://pymotw.com/3/socket/tcp.html
import socket
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the port
# (the host name used will need to be pingable from the requesting service)
server_address = ('', 10000)
print('starting up on {} port {}'.format(*server_address))
sock.bind(server_address)

# Listen for incoming connections
sock.listen(1)

while True:  # add a terminator based on your application state
    # Wait for a connection
    print('waiting for a connection')
    connection, client_address = sock.accept()
    try:
        print('connection from', client_address)

        # Receive the data in small chunks and retransmit it
        while True:
            data = connection.recv(16)
            # print('received {!r}'.format(data))
            if data:  # add a check to ensure the request is valid
                print('sending data back to the client')
                data = 'Current application state is:' + getStatus()
                connection.sendall(data.encode())
            else:
                print('no data from', client_address)
                break
    finally:
        # Clean up the connection
        connection.close()

但是,如何在每次都不重写的情况下更新XML文件呢?是否有一种方法可以“更新”XML文件(即在中间添加一个
)。正如你通过我的问题正确判断的那样,我是这里的新手。只需覆盖它并进行前端投票。这是一个很好的方法!如果您真的想保留脚本执行的整个历史记录,只需将节点添加到XML中,像lxml这样的漂亮库将使您的XML创建任务变得更加轻松。这与@Omar的JS位相结合似乎是一个很好的解决方案。