Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过WebSocket发送长时间运行的Python脚本的输出?_Python_Websocket_Subprocess_Stdout - Fatal编程技术网

如何通过WebSocket发送长时间运行的Python脚本的输出?

如何通过WebSocket发送长时间运行的Python脚本的输出?,python,websocket,subprocess,stdout,Python,Websocket,Subprocess,Stdout,用户上传我需要在服务器上执行的python文件,并将通过WebSocket创建的标准输出发回。执行的python文件将运行几分钟,我需要通过套接字返回标准输出,因为它们是实时“打印”出来的,而不是在脚本完成时 我尝试使用:,但那不是WebSocket,我的React前端无法成功连接到它。(如果你能解决这个问题,那也能解决我的问题) 我也尝试过使用websocketd,但由于无法在每个用户添加的print语句之后添加sys.stdout.flush(),因此无法解决我的问题 我也尝试过使用子流程的

用户上传我需要在服务器上执行的python文件,并将通过WebSocket创建的标准输出发回。执行的python文件将运行几分钟,我需要通过套接字返回标准输出,因为它们是实时“打印”出来的,而不是在脚本完成时

我尝试使用:,但那不是WebSocket,我的React前端无法成功连接到它。(如果你能解决这个问题,那也能解决我的问题)

我也尝试过使用
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)

此独立示例将

  • 从web套接字读取
    python
    脚本
  • 将脚本写入文件系统
  • 在禁用输出缓冲的情况下运行脚本
  • 一次读取一行脚本输出
  • 将每行输出写入web套接字
  • 导入异步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对象呢?