The events_twisted module

The soco.events_twisted module has been provided for those wanting to use soco in an application built on the twisted framework who want the event listener also to be implemented using twisted. The soco.events_twisted page contains an example of how to use the module.

The event listener is an HTTP server that receives event notifications from sonos devices. In the soco.events module, it is implemented using threading and requests. The soco.events module will apply by default, unless config.EVENTS_MODULE is set to point to the soco.events_twisted module.

Twisted is not a soco dependency. The existence of the events_twisted module is not a recommendation or endorsement of twisted. The events_twisted module has been provided because there are some soco users who use twisted.

If you wish to use events_twisted, it is assumed you already use and are familiar with the twisted framework. No guidance is provided here on how to install or use twisted.

The main differences between soco.events_twisted and soco.events are:

  • soco.events_twisted uses twisted, rather than requests, for making and receiving HTTP calls. Network calls in events_twisted return at once without blocking
  • in soco.events_twisted, the event listener runs in the main thread of execution. Threading is not used
  • soco.events_twisted requires a twisted reactor to be running in the application into which it is imported. It will not install or start a reactor
  • soco.events_twisted is not threadsafe and should run in the main thread of execution. Therefore, subscribing to events should happen in the main thread of execution. In part, this is because a Deferred is not threadsafe
  • in soco.events_twisted, if the requested port is not available, the event_listener will automatically try the next port, within a maximum range of 100 of the port initially requested
  • in soco.events_twisted, subscribe, renew and unsubscribe return a Deferred the result of which will be the soco.events_twisted.Subscription instance. The Subscription can be accessed by adding a callback to receive it. In addition, Deferred.subscription is set to refer to the Subscription. This is a simpler and quicker way to get the Subscription
  • in soco.events_twisted, Subscription.callback can be set to refer to a function that will be called each time a soco.events_base.Event is received by the Subscription. The callback will be passed the Event as the only parameter. This is likely to be the most convenient way to receive Events. If Subscription.callback is not set, or is not callable, Events will be put on the Subscription’s event queue, in the same way as for the events module.

Please note that all network calls in soco (other than those in events_twisted) are made using the requests library, which blocks. In an application based on twisted, it may be desirable to make these network calls asynchronously, so they do not block. Two solutions to consider are (a) to use threads when calling other potentially blocking soco methods or (b) to use a subprocess to handle calls to soco. Twisted provides the deferToThread method for deferring potentially blocking methods to a thread. If a subprocess is to be used, there will need to be a protocol for communication between the subprocess and the main application. For a DIY solution, twisted’s NetstringReceiver may be a useful starting point.