2009/6/4 Drew Smathers <drew.smathers@gmail.com>:
2009/6/3 Jason St.Clair <woahyeahyeah@yahoo.com>:
I've got a simple little chat server set up that people can telnet into. The code is as follows:
----------
from twisted.internet import reactor from twisted.internet.protocol import ServerFactory from twisted.protocols.basic import LineOnlyReceiver import threading
class ChatProtocol(LineOnlyReceiver):
name = ""
def getName(self): if self.name!="": return self.name return self.transport.getPeer().host
def connectionMade(self): print "New connection from "+self.getName() self.sendLine("Welcome to the chat.\r\n/quit to quit.") self.factory.sendMessageToAllClients(self.getName()+" joined the chat.") self.factory.clientProtocols.append(self)
def connectionLost(self, reason): print "Lost connection from "+self.getName() self.factory.clientProtocols.remove(self) self.factory.sendMessageToAllClients(self.getName()+" disconnected.")
def lineReceived(self, line): if line=="/quit": self.transport.loseConnection() else: self.factory.sendMessageToAllClients(self.getName()+": "+line)
def sendLine(self, line): self.transport.write(line+"\r\n")
class ChatProtocolFactory(ServerFactory):
protocol = ChatProtocol
def __init__(self): self.clientProtocols = []
def sendMessageToAllClients(self, mesg): for client in self.clientProtocols: client.sendLine(mesg)
def Test(): global test factory.sendMessageToAllClients('Hey.') test = threading.Timer(1.0, Test) test.start() test = threading.Timer(1.0, Test) test.start()
print "Starting Server" factory = ChatProtocolFactory() reactor.listenTCP(3009, factory) reactor.run()
----------
The problem is that last def, "def Test()". It should send the line "Hey." to all connected users every second. It does that - however, the message only sends through if the client is typing or has entered a line. So, if a client is idle for 30 seconds, then starts typing, he will receive "Hey." 30 times in a row - one for each second he was idle.
Is there any way to get this to send the message and have it show up for a client even when they're idle? _______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
You should use twisted.internet.task.LoopingCall instead of threading.Timer and it's also worth mentioning that twisted APIs are *not* thread-safe; in use cases where you have to use threads (there are really few), you should use reactor.callFromThread().
So the equivalent for the above using LoopingCall would be something like:
def test(): factory.sendMessageToAllClients('Hey.') task = LoopingCall(test) reactor.callWhenRunning(task.start, 1.0, 0) ...
HTH
-Drew
Also, forgot to mention: This is a general question better asked at twisted-python mailing list (not twisted-web). -Drew