[Twisted-Python] The right way to broadcast to your TCP/IP clients?

Steve Freitas sflist at ihonk.com
Sun Mar 28 21:20:17 MST 2004


Hi all,

I'm working on a chat server-ish kinda thang, and although the learning curve 
of twisted was a bit much for my last project, I'm back again for more 
punishment. In this case, I'm looking to broadcast a message from one client 
to other connected clients. I came up with a solution, but I wanted to run it 
by you guys to see whether what I'm doing is The Right Way To Do Things.

Here's what I did for my simple prototype that takes any message received from 
a client and sends it to all clients (including the sender):

-----------

factory = Factory()
factory.transports = []

class Chatterbox(Protocol):

    def connectionMade(self):
	# Make a copy of the new connection's transport and
	# stick it somewhere all the Chatterbox instances can
	# get to it.
        self.factory.transports.append(self.transport)

    def dataReceived(self, data):
	# Every time a piece of data comes in, just write it back
	# out to all the transports, ergo, clients.
        for transport in self.factory.transports:
             transport.write(data)

    def connectionLost(self, reason):
	# When a client disconnects, delete the copy of their
	# transport. Bet this'll be slow w/ lotso clients.
        self.factory.transports.remove(self.transport)

factory.protocol = Chatterbox
reactor.listenTCP(8008, factory)
reactor.run()

-----------

What do you think? Is this a properly twisted way to do things? Strike anyone 
as needlessly inefficient? I'm motivated to make it as fast as possible, so 
despite what Knuth said, any proferred optimizations would be great to hear. 
(On a related note, I intend to put the for loop into a map, but I haven't 
yet embarked on language optimizations, and this question's more about 
Twisted.)

Also, I'm obviously, and perhaps incorrectly, assuming that once a transport 
object is created, it never gets changed. If it does, the copy I made won't 
be updated -- is this a problem?

A definite problem with this method is that it sends the data right back to 
the sender, which actually isn't desirable for my application. Trouble is, to 
avoid it I think I'd have to do this...

    def dataReceived(self, data):
        for transport in self.factory.transports:
		if transport != self.transport:
	             transport.write(data)

Seems an inefficient way to do things, as I'd like this server to handle 
thousands of clients.

Anyway, any help would be appreciated. :-)

Thanks,

Steve




More information about the Twisted-Python mailing list