Twisted KatCP implementation

Twisted

Twisted KatCP is an alternative implementation of KatCP protocol using Twisted framework. Providing alternative implementation using a well known networking library has multiple advantages. Among the most important is an alternative to threads concurrency model, which work better for some cases and robustness that come from years of testing.

Using TxKatCP, clients

Note

general information how to write clients using Twisted.

The main client interface is a ClientKatCP, similar in purpose to the CallbackClient.

Interface is built around two ways of communicating. Asynchronous informs, which are not associated with any requests will be handled by overloaded inform_xyz methods, where xyz is a name of a method. Requests are sent via send_request method on the client class, which will return a deferred. Deferred will be called with a tuple ((informs, reply)) where informs is a list of katcp Message and reply is one message object.

Note

an example client is in scripts/demotxclient.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
""" This is a demo client, which cooperate with demotxserver
"""

import sys
from katcp.tx import run_client, ClientKatCPProtocol
from twisted.internet import reactor

class DemoClient(ClientKatCPProtocol):
    def inform_out_of_band(self, msg):
        print "out of band", msg

def got_sensor_value((informs, reply), protocol):
    print informs
    print reply
    reactor.stop()

def got_foo((informs, reply), protocol):
    print informs
    print reply
    protocol.send_request('sensor-value',
                          'int_sensor').addCallback(got_sensor_value, protocol)

def connected(protocol):
    print "Connected"
    protocol.send_request('foo').addCallback(got_foo, protocol)

if __name__ == '__main__':
    # override with options if necessary
    if len(sys.argv) > 1:
        port = int(sys.argv[1])
    else:
        port = 1235
    run_client(('localhost', port), DemoClient, connected)
    reactor.run()

Using TxKatCP, device servers

Note

general information how to write servers using Twisted.

The DeviceServer is very similar to DeviceServer. You overload request_xxx methods on a protocol (like DeviceProtocol) where xxx is a name of katcp request. A request method either returns a Message reply instance, possibly sending informs along the way (using self.send_message interface). Device server must overload setup_sensors method, which should register sensors by calling self.add_sensor and must provide a protocol member pointing to a correct DeviceProtocol subclass.

Note

an example server is in scripts/demotxserver.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
""" This is a demo device server for showing capabilities of twisted based
katcp implementation of a device server
"""

from twisted.internet import reactor
from katcp.tx import DeviceServer, DeviceProtocol
from katcp import Sensor, Message
from twisted.internet.protocol import Factory
from twisted.python import log
from katcp import Message
from katcp.tx.test.testserver import IntSensor, FloatSensor

PORT = 1235 # or 0

import sys

class DemoProtocol(DeviceProtocol):
    def request_foo(self, msg):
        """ This is called when ?foo is called from the other side.
        """
        # send one inform
        self.send_message(Message.inform('foo', 'fine'))
        # return reply
        return Message.reply('foo', 'ok', '1')

    def connectionMade(self):
        """ Called when a connection is made, send out-of-band inform
        """
        self.send_message(Message.inform('out-of-band'))
        DeviceProtocol.connectionMade(self)

class DemoServerFactory(DeviceServer):
    production = True # says whether halt request should stop the reactor
    # (and hence the whole process)

    protocol = DemoProtocol # meaning we're using custom protocol

    def setup_sensors(self):
        """ This is a method that overloaded provides a way to add sensors
        to the device
        """
        self.add_sensor(FloatSensor(Sensor.FLOAT, "float_sensor", "descr",
                                    "milithaum", params=[-1.0, 1.0]))
        self.add_sensor(IntSensor(Sensor.INTEGER, "int_sensor", "descr2",
                               "cows", params=[-100, 100]))


def main():
    factory = DemoServerFactory(PORT, '')
    print factory.start().getHost()
    reactor.run() # run the main twisted reactor

if __name__ == '__main__':
    main()

Table Of Contents

Previous topic

Core API

Next topic

Kattypes

This Page