【问题标题】:Streaming the state of a Python script to a website将 Python 脚本的状态流式传输到网站
【发布时间】:2010-09-17 21:47:45
【问题描述】:

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

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

我一直想将脚本的状态写入StringIO 对象(流式传输到它)并使用Javascript 刷新浏览器,但老实说我不知道​​如何实际执行此操作。

有什么建议吗?

【问题讨论】:

    标签: javascript python streaming real-time


    【解决方案1】:

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

    【讨论】:

    • 但是如何在不每次都重写的情况下更新 XML 文件呢?有没有办法“更新” XML 文件(即在中间某处添加 <node></node>)。正如你会根据我的问题正确判断的那样,我是这里的菜鸟。
    • 只需覆盖它并让前端轮询它。
    • 这是一个不错的方法!如果您真的想保留脚本执行的整个历史,只需将节点附加到 XML 中,像 lxml 这样的优秀库将使您的 xml 创建任务变得更加轻松。
    • 这与来自@Omar 的 JS 位相结合似乎是一个很好的解决方案。
    【解决方案2】:

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

    假设我的应用程序是 myapp.py,它从第 1 步到第 N 步都在工作。我会让它返回(简单文本),一个数字。这个数字是它的步数。例如,如果我调用http://localhost/myapp.py,它会返回 5。30 分钟后,我重新加载页面,它会返回 15。

    现在谈 JavaScript。我会推荐使用 jQuery。它使事情变得更容易和更快。我要做的就是

    $('#streaming').load('http://localhost/myapp.py');
    

    这会将页面内容加载到 ID = 流式传输的 DIV。但这只会在您加载页面时发生。要使其每 x 秒发生一次,请使用 JavaScript settimeout 函数。

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

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

    【讨论】:

      【解决方案3】:

      使用纯 JavaScript,您可以选择 Comet、WebSockets 和 Ajax。然而,我对其中的任何一个都不太了解。查看以下一些网站:

      http://en.wikipedia.org/wiki/Comet_(programming)

      http://www.websockets.org/

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

      【讨论】:

        【解决方案4】:

        如果您只是一个快速的解决方案而不是完整的网页,请查看SimpleHTTPServer 您可以将您的状态信息以文件的形式写入目录,然后更新它以供其他人查看。

        不漂亮,但非常快速和简单。

        对于演示,只需键入python -m SimpleHTTPServer 这将创建一个网页,其地址为http://[your computer's name or IP]:8000,其中包含启动时当前工作目录的内容。这些文件是热链接的。如果您点击一个文件,它会显示在浏览器中;如果您单击一个目录,您将切换到该目录并列出其内容。

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

        或者,查看Twisted,这将允许您直接从 Python 脚本处理 HTTP 请求。

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

        【讨论】:

          【解决方案5】:

          您可以将服务器实例添加到您的应用程序中,该服务器实例使用您的应用程序决定共享的任何内容来响应给定端口上的查询。在访问应用程序状态信息的单独线程中启动此操作,然后让您的网页或监控程序向该端口发送请求。当然,您可以以不同的方式响应不同的请求。您需要的所有信息都在 https://pymotw.com/3/socket/tcp.html 上,但下面的代码将帮助您入门:

          # 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()
          

          【讨论】:

            猜你喜欢
            • 2017-10-09
            • 2014-01-28
            • 1970-01-01
            • 2013-09-03
            • 1970-01-01
            • 2019-06-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多