【问题标题】:Continuously stream output from program in Python using Websockets使用 Websockets 在 Python 中连续流式输出程序
【发布时间】:2021-02-13 02:53:53
【问题描述】:

我想创建一个 websocket,它将程序的输出持续流式传输到 HTML 网页。

我的程序执行的过程需要 2 分钟才能完成,它会在执行时记录输出。现在,我的代码每次程序完成执行时都会更新网页,然后一次在网页上显示所有日志。我想不断更新我的网页,即:实时流式传输输出。我的服务器代码如下所示:

import nest_asyncio
nest_asyncio.apply()
import websockets
import subprocess

async def time(websocket, path):
    while True:
        command = ['myprogram', 'args']
        process = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True, bufsize=-1)
        now = process.stdout.read()
        await websocket.send(now)

start_server = websockets.serve(time, "127.0.0.1", 5670)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

我的客户端看起来像这样:

<!DOCTYPE html>
<html>
    <head>
        <title>WebSocket</title>
    </head>
    <body>
        <script>
            var ws = new WebSocket("ws://127.0.0.1:5670/"),
                messages = document.createElement('ul');
            ws.onmessage = function (event) {
                var messages = document.getElementsByTagName('ul')[0],
                    message = document.createElement('li'),
                    content = document.createTextNode(event.data);
                message.appendChild(content);
                messages.appendChild(message);
            };
            document.body.appendChild(messages);
        </script>
    </body>
</html>

关于如何做到这一点的任何想法?

【问题讨论】:

    标签: javascript python websocket real-time


    【解决方案1】:

    一种方法是使用 asyncio 的 create_subpocess_exec 命令。此处返回的 Process 实例没有等效的.poll() 方法,但您仍然可以查询returncode 属性,只要我们create_task process.wait()

    import asyncio
    import supbrocess
    
    
    async def time(websocket, path):
        while True:
            command = 'myprogram'
            args = ['a', 'r', 'g', 's']
            process = await asyncio.create_subprocess_exec(command, *args, stdout=subprocess.PIPE)
            asyncio.create_task(process.wait()) # this coroutine sets the return code
            # Must check explicitly for None because successful return codes are usually 0
            while process.returncode is None:
                now = await process.stdout.read()
                if now:
                    await websocket.send(now)
                await asyncio.sleep(0) # allow time for the wait task to complete otherwise this coroutine will always be busy
                # see: https://docs.python.org/3/library/asyncio-task.html#sleeping
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-10
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-05
      • 2021-06-20
      相关资源
      最近更新 更多