Here is a simple example of a bi-directional client and AMP server. The key is that the AMP protocol class contains a link to a client connection and provides a callRemote
method.
Of course, I only know this from digging AMP code. At best, there is a flaw in virtualization documentation, at least outside the kernel.
File: count_server.tac
from twisted.protocols.amp import AMP from twisted.internet import reactor from twisted.internet.protocol import Factory from twisted.internet.endpoints import TCP4ServerEndpoint from twisted.application.service import Application from twisted.application.internet import StreamServerEndpointService from count_client import Counter application = Application('test AMP server') endpoint = TCP4ServerEndpoint(reactor, 8750) factory = Factory() factory.protocol = Counter service = StreamServerEndpointService(endpoint, factory) service.setServiceParent(application)
File: count_client.py
if __name__ == '__main__': import count_client raise SystemExit(count_client.main()) from sys import stdout from twisted.python.log import startLogging, err from twisted.protocols import amp from twisted.internet import reactor from twisted.internet.protocol import Factory from twisted.internet.endpoints import TCP4ClientEndpoint class Count(amp.Command): arguments = [('n', amp.Integer())] response = [('ok', amp.Boolean())] class Counter(amp.AMP): @Count.responder def count(self, n): print 'received:', n n += 1 if n < 10: print 'sending:', n self.callRemote(Count, n=n) return {'ok': True} def connect(): endpoint = TCP4ClientEndpoint(reactor, '127.0.0.1', 8750) factory = Factory() factory.protocol = Counter return endpoint.connect(factory) def main(): startLogging(stdout) d = connect() d.addErrback(err, 'connection failed') d.addCallback(lambda p: p.callRemote(Count, n=1)) d.addErrback(err, 'call failed') reactor.run()
Server output:
$ twistd -n -y count_server.tac 2013-03-27 11:05:18-0500 [-] Log opened. 2013-03-27 11:05:18-0500 [-] twistd 12.2.0 (/usr/bin/python 2.7.3) starting up. 2013-03-27 11:05:18-0500 [-] reactor class: twisted.internet.epollreactor.EPollReactor. 2013-03-27 11:05:18-0500 [-] Factory starting on 8750 2013-03-27 11:05:18-0500 [-] Starting factory <twisted.internet.protocol.Factory instance at 0x2adc368> 2013-03-27 11:05:22-0500 [twisted.internet.protocol.Factory] Counter connection established (HOST:IPv4Address(TCP, '127.0.0.1', 8750) PEER:IPv4Address(TCP, '127.0.0.1', 58195)) 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] received: 1 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] sending: 2 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] received: 3 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] sending: 4 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] received: 5 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] sending: 6 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] received: 7 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] sending: 8 2013-03-27 11:05:22-0500 [Counter,0,127.0.0.1] received: 9 2013-03-27 11:05:26-0500 [Counter,0,127.0.0.1] Counter connection lost (HOST:IPv4Address(TCP, '127.0.0.1', 8750) PEER:IPv4Address(TCP, '127.0.0.1', 58195)) ^C2013-03-27 11:05:31-0500 [-] Received SIGINT, shutting down. 2013-03-27 11:05:31-0500 [-] (TCP Port 8750 Closed) 2013-03-27 11:05:31-0500 [-] Stopping factory <twisted.internet.protocol.Factory instance at 0x2adc368> 2013-03-27 11:05:31-0500 [-] Main loop terminated. 2013-03-27 11:05:31-0500 [-] Server Shut Down.
Client Output:
$ python count_client.py 2013-03-27 11:05:22-0500 [-] Log opened. 2013-03-27 11:05:22-0500 [-] Starting factory <twisted.internet.protocol.Factory instance at 0x246bf80> 2013-03-27 11:05:22-0500 [Uninitialized] Counter connection established (HOST:IPv4Address(TCP, '127.0.0.1', 58195) PEER:IPv4Address(TCP, '127.0.0.1', 8750)) 2013-03-27 11:05:22-0500 [Counter,client] received: 2 2013-03-27 11:05:22-0500 [Counter,client] sending: 3 2013-03-27 11:05:22-0500 [Counter,client] received: 4 2013-03-27 11:05:22-0500 [Counter,client] sending: 5 2013-03-27 11:05:22-0500 [Counter,client] received: 6 2013-03-27 11:05:22-0500 [Counter,client] sending: 7 2013-03-27 11:05:22-0500 [Counter,client] received: 8 2013-03-27 11:05:22-0500 [Counter,client] sending: 9 ^C2013-03-27 11:05:26-0500 [-] Received SIGINT, shutting down. 2013-03-27 11:05:26-0500 [Counter,client] Counter connection lost (HOST:IPv4Address(TCP, '127.0.0.1', 58195) PEER:IPv4Address(TCP, '127.0.0.1', 8750)) 2013-03-27 11:05:26-0500 [Counter,client] Stopping factory <twisted.internet.protocol.Factory instance at 0x246bf80> 2013-03-27 11:05:26-0500 [-] Main loop terminated.