One of the project we had at work was building a DHS (Data handling system) to be connected to an EMS (Energy measurement system) for the TGV, a quick introduction to some terms in the railways industrie, a DHS is basically a device that will connect to an existing energy measurement device and transforme the collected data then send it to a ground station.
The main language was Python, fortunately for me. To deal with the all of the network hustle, we choose Twisted for many reasons, so what is Twisted, If you want to build a web server, a mail server, an FTP client, a DNS server, or an IRC bot—clients and servers for a custom protocol in Python. And you want them to be cross-platform, RFC-compliant, testable, and deployable in a standardized fashion. What library should You use? You should use Twisted.
Twisted is a “batteries included” networking engine for writing, testing, and deploying event-driven clients and servers in Python. It comes with off-the-shelf support for popular networking protocols like HTTP, IMAP, IRC, SMTP, POP3, IMAP, DNS, FTP, Serial Port, even GPS among others.
To see just how easy it is to write networking services using Twisted, let’s run and discuss a simple Twisted TCP echo server:
from twisted.internet import protocol, reactor
def dataReceived(self, data):
Callback that will echo the received data
def buildProtocol(self, addr):
Protocol instance are created here
# Listen on the TCP connection on the port 8000
# Run the reactor main loop
In order to use Twisted at its full extend, you have to understand some key features that are embedded in Twisted, I’ll list some of them here that I think are very important:
- The reactor
The reactor is the Twisted event loop. It listens for network, filesystem, and timer events and dispatches them as they arrive to waiting event handlers. This is what makes Twisted event-driven: rather than blocking while waiting for expensive events like network requests to complete, or using threads to handle them, callbacks are registered with the event loop so events can be handled exactly when they are ready.
One of the rules that you have to keep in mind when designing programs using Twisted is never block in your callbacks or the hole event loop will be stuck at your callback, which is against the aim of the hole framework, because if you block, you will block the entire loop then lose the hole benefit ! here is to figures to ilustrate how the loop goes through the added code in the callbacks:
Transport is the abstraction Twisted use to describe the machinery linking tow end-poits, which can be a socket, Unix Socket, Serial port, etc. Transport is accessible through the protocol classes and the Factories.
Twisted Protocol is where the logic is built in, usually relying on stream-based connection semantics (Transports), such as HTTP or POP3, etc.
The Factor simply instantiates instances of a specific protocol class, Also the Factory has two methods to perform application-specific building up and tearing down , Since Twisted is battery packed with the transport implementations. The focus will be to create protocols and protocol factory that ties up a transport with protocol instance.
The Scheduler is part of the reactor, and its accessible through the api of the reactor (CallLater(), callWhenRunning(), etc.). The Scheduler of twisted introduced a monotonic clock since the version 12.0.0, in the version before, if you add callbacks to the reactor and change the time, some of them will never get called, because the clock used in the eloop was not monotonic.