# Can a Blender script stay in memory and listen to a socket?

I am considering writing a python script which, once run by the Blender internal interpreter, would stay in memory, listening to a socket and reacting to messages.

As an example I would use this to preview the currently edited object in an external engine, without having to export it to the filesystem then loading it in the engine.

How can I design a plugin to have such a behavior?

Note that this question :

• Only targets the "staying in memory / listening to a socket" part with respect to Blender inner workings, not the scene crawling/exporting, messaging details etc.
• Does not make reference to the "blender --background" mode of operation. To the contrary I would like this to work in the usual, UI-driven interface.

I am also aware of the Blender Command Port patch, but it does not seem like it has ever been merged (and I would like this to work with a "vanilla" Blender).

• Could you define stay active more clearly? – ideasman42 Feb 8 '16 at 3:05
• @ideasman42 of course. By "stay active" I mean a behavior similar to a unix daemon: "a long-running background process that answers requests for services" (source]. I'm not sure I can define this in Blender API terms since that's actually what I seek an answer for. – oparisy Feb 8 '16 at 7:00
• I edited the question title for, I hope, more clarity. – oparisy Feb 8 '16 at 7:02
• I found a related question afterwards: blender.stackexchange.com/questions/26284/…. This describes appending to bpy.app.handlers.frame_change_pre, and using threading to avoid freezing the GUI (see also blender.stackexchange.com/questions/2428/…). – oparisy Feb 8 '16 at 7:18
• A modal operator seems to be the proper way to handle this robustly: blender.stackexchange.com/questions/442/… – oparisy Feb 9 '16 at 22:07

I've used the following for a quick and dirty solution using the update on animation trick:

import bpy, mathutils, socket

TCP_IP = '192.168.1.121'
TCP_PORT = 8888
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

def updateCubeFromSocket(args):
data = s.recv(BUFFER_SIZE).decode('utf-8')
#do stuff

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


Adding in threading isn't too much harder, something like this should work too:

import time, bpy, threading
TCP_IP = '192.168.1.121'
TCP_PORT = 8888
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

while(True):
data = s.recv(BUFFER_SIZE).decode('utf-8')
#do stuff
time.sleep(0.1) #update rate in seconds