Twisted: How to sendLine from outside the LineReceiver class?

Qp qp at al.net
Mon Mar 1 04:20:59 CET 2004


Thanks a ton!  It all makes sense now, and it works in a much better way I
was thinking about (somehow returning a working transport object).

That helps a whole lot...

Thanks again,
QP

"Andrew Bennetts" <andrew-pythonlist at puzzling.org> wrote in message
news:mailman.0.1078102318.22701.python-list at python.org...
> [You'll probably get more answers to Twisted questions on the Twisted
> mailing-list: twisted-python at twistedmatrix.com]
>
> On Sun, Feb 29, 2004 at 02:06:07PM -0500, Qp wrote:
> > Hello.  I'm building a simple chat server and client interface, and I've
got
> > everything working except for this:
> >
> > While the client's basic.LineReceiver protocol class can sendLine when a
> > connection is made (that is, when the class is called automatically),
> > whenever I try to call sendLine from another class (my ClientFactory
class)
> > then I get the following error.
> >
> > "in sendLine
> > return self.transport.write(line + self.delimiter)
> > AttributeError: 'NoneType' object has no attribute 'write'"
> >
> > So, I assume the instance of the LineReceiver is not set up properly.
How
> > do I do this?
> >
> > The code I am using for the classes is as follows.  The error comes when
I
> > call chatFactory.sendMessage():
> >
> [...]
> > class chatFactory(protocol.ClientFactory):
> >     protocol = chatClient
> >
> [...]
> >     def sendMessage(self):
> >         c = chatClient()
> >         c.sendLine("Hey there")
>
> I see you are using ClientFactory, so I presume you want to make a client
> connection to a remote server with this protocol.
>
> You need to connect your protocol, not just create the object out of thin
> air.  See:
>
>     http://twistedmatrix.com/documents/howto/clients
>
> and also:
>
>
http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.I
ReactorTCP.html#connectTCP
>
> I think the easiest way to do what you need is to have the protocol's
> connectionMade signal the factory:
>
> ----
> class ChatClient(basic.LineReceiver):
>
>     def connectionMade(self):
>         self.sendLine("A new person has entered the room!")
>         self.factory.clientReady(self)
>
>     def lineReceived(self, line):
>         app.text_output.config(state=NORMAL) #enable text_output for
insert
>         app.text_output.insert(END, line +"\n")
>         app.text_output.config(state=DISABLED)
>         app.text_input.delete(0, END) #clear text_input
>         app.text_output.see(END) #move scrollbar to the bottom
>
>     def connectionLost(self, reason):
>         reactor.stop()
>
> class ChatFactory(protocol.ClientFactory):
>     protocol = ChatClient
>
>     def clientConnectionFailed(self, connector, reason):
>         reactor.stop()
>
>     def clientConnectionLost(self, connector, reason):
>         reactor.stop()
>
>     def startFactory(self):
>         self.messageQueue = []
>         self.clientInstance = None
>
>     def clientReady(self, instance):
>         self.clientInstance = instance
>         for msg in self.messageQueue:
>             self.sendMessage(msg)
>
>     def sendMessage(self, msg='Hey there'):
>         if self.clientInstance is not None:
>             self.clientInstance.sendLine(msg)
>         else:
>             self.messageQueue.append(msg)
> ----
>
> Note that I've added a simple message queue because it may take some time
> for the connection to be established, so calls to sendMessage could fail
if
> called too soon.  The queue avoids that problem.
>
> A better solution might be to not write the factory at all, and use
> twisted.internet.protocol.clientCreator:
>
>
http://twistedmatrix.com/documents/current/api/twisted.internet.protocol.Cli
entCreator.html
>
> ----
> from twisted.python import log
>
> # Create creator and connect
> clientCreator = protocol.ClientCreator(reactor, ChatClient)
> deferred = clientCreator.connectTCP(host, port)
>
> # When connected, send a line
> def connectionReady(protocol):
>     protocol.sendLine('Hey there')
> deferred.addCallback(connectionReady)
>
> # Log any errors that occur (such as connection failed)
> deferred.addErrback(log.err)
> ----
>
> -Andrew.
>
>






More information about the Python-list mailing list