Networking
Bonsai includes support for Open Sound Control (OSC), a flexible networking protocol for low-latency communication between different processes, potentially running in different devices over the network. The next exercises will show you how to leverage these primitives for connecting two Bonsai processes exchanging a variety of data. The final optional exercise shows how to leverage the OSC protocol to interface a Python script with a Bonsai workflow.
Exercise 1: Peer-to-peer UDP communication
We will start by implementing a direct peer-to-peer communication link between two processes on the same machine. This will allow us to send data between two known nodes in the network, or two independent Bonsai processes.
- Setup the above workflow.
- Set the
Nameproperty of theCreateUdpClientsource toEmitter. - Set the
RemotePortto 2342. - Set the
Connectionproperty of theSendMessagesink toEmitter.
Open a new Bonsai window and setup the following workflow:
- Set the
Nameproperty of theCreateUdpClientsource toReceiver. - Set the
Portproperty to 2342. - Set the
Connectionproperty of theReceiveMessagesource toReceiver. - Run the workflow and visualize the output of the
ReceiveMessagesource. Note the characters displayed in theTypeTag. Now change theTypeTagproperty of theReceiveMessagesource toi. This will make the source interpret the contents of the OSC message as a 32-bit integer. You can string multiple characters to describe complex messages. - If you have access to two computers over a shared network, you can try to setup one of them to be the
Emitterand the other to be theReceiver. In this case, make sure to set theRemoteHostNameproperty of theEmitterto match the IP address of the receiver computer.
Exercise 2: Client/Server TCP communication
Next we will implement a responsive TCP server with support to accept multiple connections. This will allow us to share data between multiple unknown nodes in the network, where each receiver node just needs to know the IP address of the server and establish a connection to the data stream.
- Setup the above workflow (identical to the previous exercise but using
CreateTcpServer). - Set the
Nameproperty of theCreateTcpServersource toEmitter. - Set the
Portproperty to 2342. - Set the
Connectionproperty of theSendMessagesink toEmitter.
Open a new Bonsai window and setup the following workflow:
- Set the
Nameproperty of theCreateTcpClientsource toReceiver. - Set the
Portproperty to 2342. - Set the
Connectionproperty of theReceiveMessagesource toReceiver. - Run the workflow and visualize the output of the
ReceiveMessagesource, optionally setting theTypeTagproperty toi. Try opening multiple copies of the receiver workflow and running them simultaneously. Verify that data is streamed to all instances successfully. - If you have access to two or more computers over a shared network, you can try to set up multiple remote data listeners. In this case, make sure to set the
HostNameproperty of theReceivernode to match the IP address of the receiver computer.
Exercise 3: Streaming image data
It is possible to share multiple data streams of different types simultaneously through a single OSC connection. To do this, we need to specify different OSC addresses for our messages to allow clients to subscribe to the independent streams.
- Start from the previous emitter workflow.
- Set the
Addressproperty of theSendMessagesink to/cursor. - Add a
CameraCapturesource. - Add a
ConvertToArraytransform to convert the image into an array of bytes. - Add a new
SendMessagenode with theAddressproperty set to/image. - Ensure the
Connectionproperty of the new node is set toEmitter.
Open a new Bonsai window and setup the following workflow:
- Start from the previous receiver workflow.
- Set the
Addressproperty of theReceiveMessagesource to/cursor. - Add a new
ReceiveMessagesource with theAddressproperty set to/image. - Run the emitter workflow and the receiver workflow and verify that you can receive both data streams.
- Set the
TypeTagproperty on the newReceiveMessagenode tobfor byte array. - Add a
ConvertFromArraytransform following theReceiveMessagesource. - Add a
Reshapetransform. - Set the
Channelsproperty to 3 (color image) and theRowsproperty to 480 (or your camera image height). - Add a
ConvertToImagetransform to interpret the resulting buffer as an image. - Run both the emitter and the receiver workflow and verify you can successfully receive and decode both data streams. If you have access to two or more computers over a shared network, you can try to set up multiple remote data listeners, each listening to one or both data streams.