# Python non-blocking networking

**URL:** <https://discourse.slicer.org/t/python-non-blocking-networking/11725>\
**Category:** Development\
**Tags:** multithreading, networking\
**Created:** [May 26, 2020, 11:45pm UTC](https://discourse.slicer.org/t/python-non-blocking-networking/11725 "2020-05-26T23:45:06Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![talmazov](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/talmazov/32/3966_2.png) [@talmazov](https://discourse.slicer.org/u/talmazov)\
**Post date:** [May 26, 2020, 11:45pm UTC](https://discourse.slicer.org/t/python-non-blocking-networking/11725/1 "2020-05-26T23:45:06Z")

</div>

Hey all,  
I’ve been pretty successful writing this socket client on slicer. it works but it is not responsive receiving the data, i imagine it is an issue with threading and blocking  
i start my client via a thread

```
def start():
    asyncore.loop()
    
def init_thread(run):
    new_thread = threading.Thread() # create a new thread object.
    new_thread.run = run
    new_thread.start()

class EchoClient(asyncore.dispatcher): ...

socket_obj = EchoClient(address[0], address[1])
init_thread(start)

```

but this doesn’t seem to be working very well, which i anticipated but hoped to not be the case. I am using asyncore for networking, and starting the client/server in a threaded loop. Any recommendation on how to do multiprocessing/threading or asynchronous networking in 3d slicer?

Thanks!

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [May 27, 2020, 12:04am UTC](https://discourse.slicer.org/t/python-non-blocking-networking/11725/2 "2020-05-27T00:04:55Z")

</div>

Hi -

I looked at async python, but didn’t see a good way to integrate it cleanly with the Qt event loop.

Fortunately Qt provides a QSocketNotifier class, which provides a signals/slots interface to socket events for connections, readable, and writable state changes. I’ve been using it for a while in the [SlicerWeb/WebServer.py code](https://github.com/pieper/SlicerWeb/blob/master/WebServer/WebServer.py#L1479). I think this is the cleanest way to do it.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 27, 2020, 12:24am UTC](https://discourse.slicer.org/t/python-non-blocking-networking/11725/3 "2020-05-27T00:24:58Z")

</div>

If you want to send/receive images, transforms, models or control remote hardware/software in real-time then another option is OpenIGTLink (via SlicerOpenIGTLink extension). We have interfaces implemented for real-time data exchange with various medical imaging devices, surgical navigation systems, position trackers, sensors, haptic devices, etc. If OpenIGTLink interface is not yet available for all the external device/software that you want to use then it is not hard to implement it, as OpenIGTLink is a very simple simple socket-based protocol. We already have many modules (mainly in [SlicerIGT extension](http://www.slicerigt.org/wp/)) that works very nicely with OpenIGTLink - you can reslice a volume with positions you receive from an external position tracker, reconstruct volume from tracked slices, display information for real-time surgical tool navigation, etc.

What is your use case? What information you would like to exchange, with what hardware/software?

---

<div class="post-metadata">

**Author:** ![talmazov](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/talmazov/32/3966_2.png) [@talmazov](https://discourse.slicer.org/u/talmazov)\
**Post date:** [May 29, 2020, 2:41am UTC](https://discourse.slicer.org/t/python-non-blocking-networking/11725/4 "2020-05-29T02:41:29Z")

</div>

the WebServer example was amazing, just what I needed. I managed to work this out [lines 19-90]

> <https://github.com/dentsoft-foundation/linkSlicerBlender/blob/socket/slicer_link/slicer_module/comm/asyncsock.py>

something i noticed that i am not sure is normal or not. When i create the socket and start it then connecting QSocketNotifier Read to activate seems to put the socket thread in some kind of a loop that puts one of my CPU core utilization 100%, slicer runs on a separate core well. the core utilization goes down when i disconnect QSocketNotifier read but then i can’t poll for incoming data…  
am i not using QSocketNotifier correctly? am i suppose to connect/activate the event manually? if so how can i poll for incoming data without putting the CPU core to 100% utilization?

thanks!

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 29, 2020, 3:05am UTC](https://discourse.slicer.org/t/python-non-blocking-networking/11725/5 "2020-05-29T03:05:52Z")

</div>

Probably you need to put in a short sleep in the polling loop. See for example [here](https://stackoverflow.com/questions/22423625/python-asyncore-using-100-cpu-after-client-connects).

---

<div class="post-metadata">

**Author:** ![talmazov](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/talmazov/32/3966_2.png) [@talmazov](https://discourse.slicer.org/u/talmazov)\
**Post date:** [May 30, 2020, 12:53am UTC](https://discourse.slicer.org/t/python-non-blocking-networking/11725/6 "2020-05-30T00:53:07Z")

</div>

i found QTcpSocket() to work really well!!!  
here is the final implementation, CPU utilization is great as well as response time 😃  
thanks for all your help guys!

> <https://github.com/dentsoft-foundation/linkSlicerBlender/blob/socket/slicer_link/slicer_module/comm/asyncsock.py>
