简体   繁体   中英

Twisted client for a send only protocol that is tolerant of disconnects

I've decided to dip my toe into the world of asynchronous python with the help of twisted. I've implemented some of the examples from the documentation, but I'm having a difficult time finding an example of the, very simple, client I'm trying to write.

In short I'd like a client which establishes a tcp connection with a server and then sends simple "\\n" terminated string messages off of a queue object to the server. The server doesn't ever respond with any messages so my client is fully unidirectional. I /think/ that what I want is some combination of this example and the twisted.internet.protocols.basic.LineReceiver convenience protocol. This feels like it should be just about the simplest thing one could do in twisted, but none of the documentation or examples I've seen online seem to fit quite right.

What I have done is not used a Queue but I am illustrating the code that sends a line, once a connection is made. There are bunch of print stuff that will help you understand on what is going on.

Usual import stuff:

from twisted.web import proxy
from twisted.internet import reactor
from twisted.internet import protocol
from twisted.internet.protocol import ReconnectingClientFactory 
from twisted.protocols import basic
from twisted.python import log
import sys
log.startLogging(sys.stdout)

You create a protocol derived from line receiver, set the delimiter. In this case, I simply write a string "www" once the connection is made. The key thing is to look at protocol interface at twisted.internet.interface.py and understand the various methods of protocol and what they do and when they are called.

class MyProtocol(basic.LineReceiver):

    #def makeConnection(self, transport):
    #    print transport       

    def connectionLost(self, reason):
        print reason
        self.sendData = False

    def connectionMade(self):
        print "connection made"
        self.delimiter = "\n"
        self.sendData = True
        print self.transport
        self.sendFromQueue()

    def sendFromQueue(self):
        while self.sendData:
            msg = dataQueue.get()
            self.sendLine(msg)
            # you need to handle empty queue
            # Have another function to resume 

Finally, A protocol factory that will create a protocol instance for every connection. Look at method : buildProtcol.

class myProtocolFactory():
    protocol = MyProtocol

    def doStart(self):
        pass

    def startedConnecting(self, connectorInstance):
        print connectorInstance

    def buildProtocol(self, address):
        print address
        return self.protocol()

    def clientConnectionLost(self, connection, reason):
        print reason
        print connection

    def clientConnectionFailed(self, connection, reason):
        print connection
        print reason

    def doStop(self):
        pass

Now you use a connector to make a connection:

reactor.connectTCP('localhost', 50000, myProtocolFactory())
reactor.run()

I ran this and connected it to an server that simply prints what it receives and hence send no ack back. Here is the output:

1286906080.08   82     INFO 140735087148064 __main__ conn_made: client_address=127.0.0.1:50277
1286906080.08   83    DEBUG 140735087148064 __main__ created handler; waiting for loop
1286906080.08   83    DEBUG 140735087148064 __main__ handle_read
1286906080.08   83    DEBUG 140735087148064 __main__ after recv
'www\n'

Recieved: 4

The above example if not fault tolerant. To reconnect , when a connection is lost, you can derive your protocol factory from an existing twisted class - ReconnectingClientFactory. Twisted has almost all the tools that you would need :)

class myProtocolFactory(ReconnectingClientFactory):
    protocol = MyProtocol

    def buildProtocol(self, address):
        print address
        return self.protocol()

For further reference

I suggest that you read : http://krondo.com/?page_id=1327

[Edited: As per comment below]

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM