如何通过WebSocket发送长时间运行的Python脚本的输出?
用户上传我需要在服务器上执行的python文件,并将通过WebSocket创建的标准输出发回。执行的python文件将运行几分钟,我需要通过套接字返回标准输出,因为它们是实时“打印”出来的,而不是在脚本完成时 我尝试使用:,但那不是WebSocket,我的React前端无法成功连接到它。(如果你能解决这个问题,那也能解决我的问题) 我也尝试过使用如何通过WebSocket发送长时间运行的Python脚本的输出?,python,websocket,subprocess,stdout,Python,Websocket,Subprocess,Stdout,用户上传我需要在服务器上执行的python文件,并将通过WebSocket创建的标准输出发回。执行的python文件将运行几分钟,我需要通过套接字返回标准输出,因为它们是实时“打印”出来的,而不是在脚本完成时 我尝试使用:,但那不是WebSocket,我的React前端无法成功连接到它。(如果你能解决这个问题,那也能解决我的问题) 我也尝试过使用websocketd,但由于无法在每个用户添加的print语句之后添加sys.stdout.flush(),因此无法解决我的问题 我也尝试过使用子流程的
websocketd
,但由于无法在每个用户添加的print语句之后添加sys.stdout.flush()
,因此无法解决我的问题
我也尝试过使用子流程的管道功能,但也有同样的刷新问题
async def time(websocket, path):
while True:
data = "test"
await websocket.send(data)
# Run subprocess to execute python file in here
# sys.stdout => websocket.send
start_server = websockets.serve(time, "127.0.0.1", 5678)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
这是我正在使用的python
测试脚本:
从时间导入睡眠
对于范围(40)内的i:
印刷品(一)
睡眠(0.1)
此独立示例将
python
脚本导入异步IO
导入WebSocket
导入子流程
异步定义时间(websocket,路径):
script\u name='script.py'
script=wait websocket.recv()
打开(脚本名称为“w”)作为脚本文件:
script_file.write(脚本)
使用subprocess.Popen(['python3','-u',script_name],
stdout=子流程.PIPE,
bufsize=1,
universal_newlines=True)作为进程:
对于process.stdout中的行:
line=line.rstrip()
打印(f“line={line}”)
等待websocket。发送(行)
start_server=websockets.service(time,“127.0.0.1”,5678)
asyncio.get_event_loop()。运行_直到完成(启动服务器)
asyncio.get_event_loop().永远运行_()
我使用这个javascript
代码来测试服务器:
const WebSocket = require('ws');
let socket = new WebSocket("ws://127.0.0.1:5678");
socket.onopen = function(e) {
let script = '\
import time\n\
for x in range(100):\n\
print(f"x = {x}")\n\
time.sleep(0.25)\n\
';
console.log("sending data...");
socket.send(script);
console.log("done.");
};
socket.onmessage = function(event) {
console.log(event.data.toString());
};
socket.onerror = function(event) {
console.log(event);
};
Popen
的使用基于对该问题的回答:
-u
选项被传递给python
to。此类将用作服务器的包装器
导入系统
类服务器包装器:
定义初始化(自我,ws):
self.\uuuws=ws
sys.stdout=self
def写入(自身、数据):
自发送(数据)
def关闭(自我):
sys.stdout=sys.\u stdout__
您需要使用websocket对其进行初始化
每次调用print时都会调用write函数(因为我们将sys.stdout
更改为自定义输出)
然后,在执行完脚本后,可以使用close
导入异步
导入WebSocket
导入子流程
导入系统
类服务器包装器:
定义初始化(自我,ws):
self.\uuuws=ws
sys.stdout=self
def写入(自身、数据):
自发送(数据)
def关闭(自我):
sys.stdout=sys.\u stdout__
异步定义时间(websocket,路径):
包装器=服务器包装器(websocket)
#获取命令并像平常一样执行它们
#您不必担心读取和发送输出
start_server=websockets.service(time,“127.0.0.1”,5678)
asyncio.get_event_loop()。运行_直到完成(启动服务器)
asyncio.get_event_loop().永远运行_()
你能不能创建一个类似文件的对象,设置sys.stdout
,然后覆盖write
函数来发送数据?@通过套接字将标准输出发送回客户端,而不是在其运行完成后,这是需要添加到问题中的详细信息。从当前版本的问题来看,这些都不明显。无需道歉。有时人们没有意识到需要在问题中添加澄清的注释,以便不是每个人都能看到它。随着更新的答案,`for line in process.stdout:`循环直到长时间运行的python脚本完成执行后才会执行。有没有办法获取实时日志?下面是我正在执行的脚本以测试:从时间导入范围(40)内的I的睡眠:打印(I)睡眠(0.1)你能告诉我如何将其应用到我现有的codeself中吗?\u ws是一种类型,没有发送函数,我说过..我从未使用过这个库。那么我如何获取websocket对象呢?