As I am going through the example in this blog , I found that when ClientFactory instance, which is an argument to PoetryClientFactory, or Protocol instance, which is an argument to PoetryProtocol, is not implementing all the functions defined for ClientFactory or Protocol interface. ClientFactory interface implements startedConnecting, clientConnectionFailed, and clientConnectionLost, but PoetryClientFactory does not implement startedConnecting and clientConnectionLost. What is happening?
# This is the Twisted Get Poetry Now! client, version 2.0.
# NOTE: This should not be used as the basis for production code.
import datetime, optparse
from twisted.internet.protocol import Protocol, ClientFactory
def parse_args():
usage = """usage: %prog [options] [hostname]:port ...
This is the Get Poetry Now! client, Twisted version 2.0.
Run it like this:
python get-poetry.py port1 port2 port3 ...
If you are in the base directory of the twisted-intro package,
you could run it like this:
python twisted-client-2/get-poetry.py 10001 10002 10003
to grab poetry from servers on ports 10001, 10002, and 10003.
Of course, there need to be servers listening on those ports
for that to work.
"""
parser = optparse.OptionParser(usage)
_, addresses = parser.parse_args()
if not addresses:
print parser.format_help()
parser.exit()
def parse_address(addr):
if ':' not in addr:
host = '127.0.0.1'
port = addr
else:
host, port = addr.split(':', 1)
if not port.isdigit():
parser.error('Ports must be integers.')
return host, int(port)
return map(parse_address, addresses)
class PoetryProtocol(Protocol):
poem = ''
task_num = 0
def dataReceived(self, data):
self.poem += data
msg = 'Task %d: got %d bytes of poetry from %s'
print msg % (self.task_num, len(data), self.transport.getPeer())
def connectionLost(self, reason):
self.poemReceived(self.poem)
def poemReceived(self, poem):
self.factory.poem_finished(self.task_num, poem)
class PoetryClientFactory(ClientFactory):
task_num = 1
protocol = PoetryProtocol # tell base class what proto to build
def __init__(self, poetry_count):
self.poetry_count = poetry_count
self.poems = {} # task num -> poem
def buildProtocol(self, address):
proto = ClientFactory.buildProtocol(self, address)
proto.task_num = self.task_num
self.task_num += 1
return proto
def poem_finished(self, task_num=None, poem=None):
if task_num is not None:
self.poems[task_num] = poem
self.poetry_count -= 1
if self.poetry_count == 0:
self.report()
from twisted.internet import reactor
reactor.stop()
def report(self):
for i in self.poems:
print 'Task %d: %d bytes of poetry' % (i, len(self.poems[i]))
def clientConnectionFailed(self, connector, reason):
print 'Failed to connect to:', connector.getDestination()
self.poem_finished()
def poetry_main():
addresses = parse_args()
start = datetime.datetime.now()
factory = PoetryClientFactory(len(addresses))
from twisted.internet import reactor
for address in addresses:
host, port = address
reactor.connectTCP(host, port, factory)
reactor.run()
elapsed = datetime.datetime.now() - start
print 'Got %d poems in %s' % (len(addresses), elapsed)
if __name__ == '__main__':
poetry_main()
I don't think I'm quite sure what you're asking, but essentially if you don't need to act on a certain event (such as when a client starts connecting or a connection is lost), you don't need to implement that function. It's just an interface mostly. If you don't implement those functions, an empty function that does nothing is called, from ClientFactory
or Protocol
, or whichever class you inherit from..
If you are implementing an interface yourself, it looks like this:
from zope.interface import implementer
from twisted.internet.interfaces import IProtocol
@implementer(IProtocol)
class MyProtocol(object):
" ... "
In this case, you do need to implement all methods, because this @implementer
declaration is just saying that you intend to provide all the relevant methods.
However, the more common thing to do in Twisted is to subclass, like this:
from twisted.internet.protocol import Protocol
class MyProtocol(Protocol, object):
" ... "
In this case, you do not need to implement all methods, because the Protocol
super-class already provides implementations of all the methods on IProtocol
. In general, Twisted provides a superclass that has default or empty versions of all the methods for many of the more frequently-used interfaces that Twisted application developers must implement.
I'm not quite sure what you're asking, too.
IMO, reaching github for their source code is the fastest way to learn. As you can see, there are default implementation for startedConnecting and clientConnectionLost (empty code, though).
Therefore, you just need to implement callbacks you need but not all methods defined in that interface.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.