Created
May 14, 2017 13:49
-
-
Save yc0/92fafae1b5457f10dfd6e64ab64a0fe4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is the Twisted Get Poetry Now! client, version 2.1. | |
# NOTE: This should not be used as the basis for production code. | |
import optparse,sys | |
from twisted.internet.protocol import Protocol, ClientFactory | |
from twisted.internet import reactor | |
from twisted.python.failure import Failure | |
def parse_args(): | |
usage = """usage: %prog [options] [hostname]:port ... | |
This is the Get Poetry Now! client, Twisted version 2.1. | |
Run it like this: | |
python get-poetry-simple.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-simple.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 = '' | |
timeout = None | |
def dataReceived(self, data): | |
self.poem += data.decode('utf-8') | |
def connectionLost(self, reason): | |
if self.delayedTimeout.active(): | |
self.delayedTimeout.cancel() | |
self.poemReceived(self.poem) | |
def poemReceived(self, poem): | |
self.factory.poem_finished(poem) | |
def connectionMade(self): | |
self.delayedTimeout = reactor.callLater(1,self.timeouthandler,Failure(TimeoutException(),TimeoutException)) | |
def timeouthandler(self,failure): | |
self.factory.errback(failure) | |
self.transport.loseConnection() | |
class TimeoutException(Exception): | |
def __init__(self): | |
self.message = "timeout exception" | |
def __str__(self): | |
return repr(self.message) | |
class PoetryClientFactory(ClientFactory): | |
protocol = PoetryProtocol # tell base class what proto to build | |
def __init__(self, callback,errback,timeout): | |
self.callback = callback | |
self.errback = errback | |
self.timeout = timeout | |
def buildProtocol(self, addr): | |
proto = ClientFactory.buildProtocol(self,addr) | |
proto.timeout = self.timeout | |
return proto | |
def poem_finished(self, poem=None): | |
self.callback(poem) | |
def clientConnectionFailed(self, connector, reason): | |
''' | |
reason : A Failure object records Exception and possibly trackback | |
''' | |
self.errback(reason) | |
print("invoke after get_poetry") | |
def get_poetry(host,port,callback,errback,timeout): | |
from twisted.internet import reactor | |
factory = PoetryClientFactory(callback,errback,timeout) | |
reactor.connectTCP(host,port,factory) | |
def poetry_main(): | |
addresses = list(parse_args()) | |
from twisted.internet import reactor | |
poems = [] | |
errs = [] | |
def get_poem(poem): | |
poems.append(poem) | |
poem_done() | |
def poem_failed(err): | |
from twisted.internet.error import ConnectionRefusedError | |
r = err.trap(ConnectionRefusedError, TimeoutException) | |
if r == TimeoutException: | |
print('Timeout Now') | |
else: | |
print("Connection Problem") | |
errs.append(err) | |
print("Poem Failed:",err, file=sys.stderr) | |
poem_done() | |
def poem_done(): | |
if len(poems) + len(errs) == len(addresses): | |
reactor.stop() | |
for addr in addresses: | |
host,port = addr | |
get_poetry(host, port, get_poem,poem_failed, 2) | |
print("exercise 3") | |
reactor.run() | |
for poem in poems: | |
print(poem) | |
if __name__ == '__main__': | |
poetry_main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment