Your sessions
list on ChatServer
contains all of the ChatSession
instances representing connections to your server.
This includes the ChatSession
that sent a particular message to the server. If you want to send that message out to all of the other connections, then you just need to skip one of the ChatSession
instances in the loop inside broadcast
. To know which one to skip, you might add an argument to broadcast:
def broadcast(self, line, skip):
And then use it to not call push
one time through the loop:
for session in self.sessions:
if session is skip:
session.push('Alternate pedagogical output\r\n')
else:
session.push('>>' + line + '\r\n')
Here I haven't actually skipped the session, just gave it different treatment so you can easily tell that something different is happening to it (instead of seeing no output, which could also be caused by some other bug...)
Now you just need to change the caller to pass this argument. Fortunately, the caller is a method of ChatSession
where the correct ChatSession
to skip is easily available - as self
!
So just change the found_terminate
method of ChatSession
to look like...
def found_terminator(self):
line = "".join(self.data)
self.data = []
self.server.broadcast(line, skip=self)
As you can see, this isn't really taking advantage of any asyncore or asynchat features. It's just some more logic in your application code.
Incidentally, Twisted is a lot more featureful than asynchat - so I recommend you spend your time learning that, instead. For a taste, here's your chat server written with Twisted:
from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineOnlyReceiver
PORT = 55555
class ChatSession(LineOnlyReceiver):
def connectionMade(self):
print "Connection from", self.transport.getPeer()
self.factory.sessions.append(self)
def connectionLost(self, reason):
self.factory.sessions.remove(self)
def lineReceived(self, line):
self.factory.broadcast(line, skip=self)
def send(self, line):
self.sendLine('>>' + line)
class ChatServer(Factory):
protocol = ChatSession
def __init__(self):
self.sessions = []
def broadcast(self, line, skip):
for session in self.sessions:
if session is not skip:
session.send(line)
reactor.listenTCP(PORT, ChatServer())
reactor.run()