Twisted client protocol - attaching an interface frontend

风流意气都作罢 提交于 2019-12-25 04:03:28

问题


I am following the tutorial on writing a client/server pair in Twisted located here:

http://twistedmatrix.com/documents/current/core/howto/clients.html

I have everything working for the communication of my client and server, the system uses custom prefixes to denote how far it is into the 'conversation'. It sends a json string initially to set up the session, and then sends a file line by line. It's really just an exercise more than anything else.

Client.py:

class ClientProtocol(protocol.Protocol):

    def connectionMade(self):
        json_string = json.dumps({
            'uid':ObjectId(),
            'lat':43.78,
            'lon':-72.5831
        },cls=Encoder)
        self.transport.write('OPN|'+json_string)
        self.fileObject = open('test.csv')

    def sendFile(self):
        lineData = self.fileObject.readline()
        if lineData != '':
            self.transport.write('UPD|')
            self.transport.write(lineData)
        else:
            self.transport.write('EOF|done')

    def dataReceived(self,data):
        if data in ['ELLO','RECVD']:
            self.sendFile()


class ClientFactory(protocol.Factory):
    def buildProtocol(self,addr):
        return ClientProtocol()

if __name__ == '__main__':
    point = TCP4ClientEndpoint(reactor,'localhost',5000)
    d = point.connect(ClientFactory())
    reactor.run()

Server:

    class TransferProtocol(protocol.Protocol):

        ran = 0

        def connectionLost(self,reason):
            print reason

        def connectionMade(self):
            self.fileObject = open('output','w')

        def dataReceived(self,data):
            methods = {'OPN':'open','UPD':'upload','EOF':'endfile'}
            if data[0:3] in methods.keys():
                func = getattr(self,methods[data[0:3]])
                func(data[4:])

        def open(self,data):
            print 'OPEN %s' % data
            self.transport.write('ELLO')

        def endfile(self,data):
            print 'END %s' % data
            self.transport.loseConnection()

        def upload(self,data):
            self.ran+=1
            self.fileObject.write(data)
            self.transport.write('RECVD')

class myProtocolFactory(protocol.Factory):
    protocol = TransferProtocol

    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

if __name__ == '__main__':
    reactor.listenTCP(5000, myProtocolFactory())
    reactor.run()

Currently, I run the server in one terminal and the client in another. As expected, both reactors start and communicate once, the client transmits it's identity json followed by the file contents and then terminates the connection. What I can't understand is how to 'hook up' this protocol to something like the cmd interface, to make it spawn these processes on command after one ends. Because the reactor in the client runs indefinitely, it performs the network conversation once and then just loops through continuously in the reactor.

Everything I've ever build with Twisted, client or server, just responded to network calls, so I am wondering what would be the correct approach to making this a "one-shot" client protocol that would activate on input commands from cmd. Would one even use the reactor for something like this? Or Twisted at all for that matter as opposed to just manually opening sockets that follow the protocol?

EDIT

I've found the Twisted stdio library fishing around on google and SO, but I'm having trouble hooking the terminal input protocol up to the network protocol.

I have the terminal protocol inherit for LineReceiver, and the prompts show correctly. I've assigned the network factory to the terminal protocol's factory object, and then attempt to call methods of the network protocol from the prompt. The problem is, the connector object assigned to this property doesn't use any of the methods of the protocol it's supposed to create.

I've put it on GitHub for brevity's sake:

https://github.com/DeaconDesperado/swfty-share/blob/master/client.py


回答1:


No There is no need for external wiring for bringing both your server and client services up together.

Twisted provides the necessary means to ensure that it can start all your services and bring them down when you shut down a twisted application. It provides the facility to do this.

Read this excellent tutorial on twisted application:

  1. http://krondo.com/?p=2345

Read the following for more details:

  1. http://twistedmatrix.com/documents/current/core/howto/basics.html
  2. http://twistedmatrix.com/documents/current/core/howto/application.html
  3. http://twistedmatrix.com/documents/current/core/howto/plugin.html
  4. http://twistedmatrix.com/documents/current/core/howto/tap.html

On SO:

  1. Twisted application without twistd


来源:https://stackoverflow.com/questions/11297032/twisted-client-protocol-attaching-an-interface-frontend

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!