4
$\begingroup$

I'm running a WSS server from a Python script to get certain data from the client. I'd like to receive that data in Blender and use it. I run the process like:

import bpy
from subprocess import Popen, PIPE
import sys

server = Popen([sys.executable, "wss.py"], stdout=PIPE)

def update(scene):
    print(server.stdout.readline())

bpy.app.handlers.frame_change_pre.append(update)

Problem is, attempting to access stdout in any way (stdout.read() or for line in stdout:) results in Blender waiting for the server process to finish running and freezing. Are there any workarounds for this?

wss.py is as follows, server works fine, but requires an asyncio loop and the process to be running:

import asyncio
import SSL
import websockets
import json
import sys

CONNECTION = None

async def onconnect(websocket, path):
    global CONNECTION
    CONNECTION = websocket
    asyncio.get_event_loop().create_task(messages(websocket))
    try:
        await websocket.wait_closed()
    finally:
        CONNECTION = None

async def messages(websocket):
    while True:
        msg = await websocket.recv()
        sys.stdout.write(msg)
        sys.stdout.flush()

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain('host.pem', 'host.key')

server = websockets.serve(onconnect, '0.0.0.0', 8000, ssl=ssl_context)

asyncio.get_event_loop().run_until_complete(server)
asyncio.get_event_loop().run_forever()
$\endgroup$
6
  • $\begingroup$ Have you tried using a pdb.set_trace() to see where exactly in the code it's hanging? I'm wondering if it's getting stuck inside the wss.py file or if it's something going on in the source code of the stdout.readline() method. $\endgroup$
    – Jakemoyo
    Jun 27 at 14:36
  • $\begingroup$ I also wonder if it's possible to use Popen.communicate() to set an explicit timeout to possibly snap it out of the async loop? $\endgroup$
    – Jakemoyo
    Jun 27 at 14:38
  • $\begingroup$ @Jakemoyo I'm sorry, as I am not very familiar with Python, so I don't really know what I should expect from pdb. Setting a timeout will always result in TimeoutExpired and no value returned by communicate(). $\endgroup$
    – GreatCorn
    Jun 27 at 15:30
  • $\begingroup$ pdb is the builtin debugging tool for python. Usually you put a line like import pdb; pdb.set_trace() above where you want to set a breakpoint and then run the program, and you can step through each line of code being executed and see where it's getting stuck. That might give you a bit more insight on what's holding it up. $\endgroup$
    – Jakemoyo
    Jun 27 at 18:00
  • $\begingroup$ @Jakemoyo The code hangs at server.stdout.readline() until I manually stop the python.exe process, which is running wss.py. I put the breakpoint before the call and stepping once froze pdb too. After stopping the process, pdb didn't reveal anything more than Blender's default drawing methods. $\endgroup$
    – GreatCorn
    Jun 28 at 8:42

1 Answer 1

1
$\begingroup$

I have a very similar issue. A workaround for me is to append to a text file in the subprocess, and then read from that in the main loop. This most likely has large drawbacks, but it is functional.

$\endgroup$
1
  • $\begingroup$ Similar approach could use writing to/reading from registry, however, I have to compare the performance on this. $\endgroup$
    – GreatCorn
    Jul 5 at 9:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.