3 # Copyright (c) Twisted Matrix Laboratories.
4 # See LICENSE for details.
7 This is a sample implementation of a Twisted push producer/consumer system. It
8 consists of a TCP server which asks the user how many random integers they
9 want, and it sends the result set back to the user, one result per line,
10 and finally closes the connection.
13 from sys import stdout
14 from random import randrange
16 from zope.interface import implements
17 from twisted.python.log import startLogging
18 from twisted.internet import interfaces, reactor
19 from twisted.internet.protocol import Factory
20 from twisted.protocols.basic import LineReceiver
23 class Producer(object):
25 Send back the requested number of random integers to the client.
28 implements(interfaces.IPushProducer)
30 def __init__(self, proto, count):
36 def pauseProducing(self):
38 When we've produced data too fast, pauseProducing() will be called
39 (reentrantly from within resumeProducing's sendLine() method, most
40 likely), so set a flag that causes production to pause temporarily.
43 print 'Pausing connection from %s' % self._proto.transport.getPeer()
45 def resumeProducing(self):
47 Resume producing integers.
49 This tells the push producer to (re-)add itself to the main loop and
50 produce integers for its consumer until the requested number of integers
51 were returned to the client.
55 while not self._paused and self._produced < self._goal:
56 next_int = randrange(0, 10000)
57 self._proto.sendLine('%d' % next_int)
60 if self._produced == self._goal:
61 self._proto.transport.unregisterProducer()
62 self._proto.transport.loseConnection()
64 def stopProducing(self):
66 When a consumer has died, stop producing data for good.
68 self._produced = self._goal
71 class ServeRandom(LineReceiver):
73 Serve up random integers.
76 def connectionMade(self):
78 Once the connection is made we ask the client how many random integers
79 the producer should return.
81 print 'Connection made from %s' % self.transport.getPeer()
82 self.sendLine('How many random integers do you want?')
84 def lineReceived(self, line):
86 This checks how many random integers the client expects in return and
87 tells the producer to start generating the data.
89 count = int(line.strip())
90 print 'Client requested %d random integers!' % count
91 producer = Producer(self, count)
92 self.transport.registerProducer(producer, True)
93 producer.resumeProducing()
95 def connectionLost(self, reason):
96 print 'Connection lost from %s' % self.transport.getPeer()
101 factory.protocol = ServeRandom
102 reactor.listenTCP(1234, factory)