问题描述
我想创建一个 websocket,它将不断地将程序的输出流式传输到 HTML 网页.
I would like to create a websocket which will continuosly stream output from the program to the HTML webpage.
我的程序执行的过程需要 2 分钟才能完成,并在执行时记录输出.现在,我的代码每次程序完成执行时都会更新网页,然后立即显示网页上的所有日志.我想不断更新我的网页,即:实时流式传输输出.我的服务器代码如下所示:
Process that my program executes takes 2 minutes to complete and it logs the outputs while it executes. Right now, my code updates the webpage everytime the program finishes executing and then displays all the logs on the webpage at once. I would like to continuosly update my webpage, i.e.: stream the output in realtime. My server code looks like this:
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()
我的客户端看起来像这样:
And my client side looks like this:
<!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>
关于如何做到这一点的任何想法?
Any ideas on how this can be done?
推荐答案
这样做的一种方法是使用 asyncio 的 create_subpocess_exec 命令.此处返回的 Process 实例没有等效的 .poll()
方法,但您仍然可以查询 returncode
属性,只要我们 create_task
process.wait()
One way of doing this is to use asyncio's create_subpocess_exec command. The Process instance returned here doesn't have an equivalent
.poll()
method, but you can still query for the returncode
attribute as long as we create_task
the 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
这篇关于使用 Websockets 从 Python 程序连续输出流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!