Method of communicating with the server

Not intending to do anything here: just curious. How does the GUI communicate with the server? Is the communication protocol easy to understand/fully documented?


As far as I’m aware it’s not documented, but it’s not too complicated, it’s just OSC.

There are (unsupported) command-line tools that communicate with the server (so you can run it without the GUI at all if you like) such as sonic-pi-tool (written in Rust), which I’ve ported to Python here.


Be aware if you are going to use this of a recent change made to to the 3.2dev source code.
commit #d245d93c5b797ad76fa333f829c32d67480af96c

This will affect future releases

Server - breaking change - improve port detection and initialisation

Most ports are now auto-allocated in a free port range (51234+). The next free port is chosen for each service to avoid conflict with existing services running on a given machine.

This is with exception of the following ports:

OSC cues port - this is now listening on port 4560
Erlang router - this is now listening on port 4561
Websockets    - this is now listening on port 4562

Ports 4560, 4561 and 4562 are currently unregistered on the Iana Service Name and Transport Protocol Port Number Registry:

Additionally, in the top-level config site it’s possible to pair the following ports:

* gui-send-to-server (to server_listen_to_gui)
* server-send-to-gui (to gui_listen_to_server)
* scsynth-send (to scsynth)

This is achieved by specifying their port number as the symbol :paired. For all ports, it’s possible to specify a port value of :dynamic for which a port number will be automatically found and chosen.

It will be eventually possible to set these ports by editing a file in ~/.sonic-pi/

So to clarify, the QT gui takes the ruby source (ie: the composition) and converts it to OSC to send to the server ?

Yes, I believe so, which is why there’s a limit to how much code it can handle before it runs into problems, as it must all fit in one UDP packet.
And other things, like the stop button, are also sent as OSC to the server.

That’s also why run_file gets round the buffer limit because the data in the file is accessed directly and not passed by OSC.