sockets - Python chat with asynchat getting session data -
i have code here:
#!/usr/bin/python asyncore import dispatcher asynchat import async_chat import socket, asyncore port = 55555 name = 'chatline' class chatsession(async_chat): def __init__(self,server,sock): async_chat.__init__(self, sock) self.server = server self.set_terminator("\r\n") self.data = [] def collect_incoming_data(self, data): self.data.append(data) def found_terminator(self): line = "".join(self.data) self.data = [] self.server.broadcast(line) def handle_close(self): async_chat.handle_close(self) self.server.disconnect(self) class chatserver(dispatcher): def __init__(self, port, name): dispatcher.__init__(self) self.create_socket(socket.af_inet, socket.sock_stream) self.set_reuse_addr() self.bind(("",port)) self.listen(5) self.name = name self.sessions = [] def disconnect(self, sessions): self.sessions.remove(session) def broadcast(self, line): session in self.sessions: session.push('>>' + line + '\r\n') def handle_accept(self): conn, addr = self.accept() print "connected " + str(addr) self.sessions.append(chatsession(self, conn)) if __name__ == '__main__': s = chatserver(port, name) try: asyncore.loop() except keyboardinterrupt: print
if connect using putty/telnet or other software i'm getting output:
test >>test
first test
i'm sending , second >>>test
server broadcasts back.
how can remove broadcast of same message send, won't second >>>test
? maybe can register session id or other data , when server broadcast message can send data sessions except session recorded previously?
or maybe can add usernames , use remove repeated message?
i didn't find tutorial or documentation asyncore or asychat, appreciated.
your sessions
list on chatserver
contains of chatsession
instances representing connections server.
this includes chatsession
sent particular message server. if want send message out of other connections, need skip 1 of chatsession
instances in loop inside broadcast
. know 1 skip, might add argument broadcast:
def broadcast(self, line, skip):
and use not call push
1 time through loop:
session in self.sessions: if session skip: session.push('alternate pedagogical output\r\n') else: session.push('>>' + line + '\r\n')
here haven't skipped session, gave different treatment can tell different happening (instead of seeing no output, caused other bug...)
now need change caller pass argument. fortunately, caller method of chatsession
correct chatsession
skip available - self
!
so change found_terminate
method of chatsession
like...
def found_terminator(self): line = "".join(self.data) self.data = [] self.server.broadcast(line, skip=self)
as can see, isn't taking advantage of asyncore or asynchat features. it's more logic in application code.
incidentally, twisted lot more featureful asynchat - recommend spend time learning that, instead. taste, here's chat server written twisted:
from twisted.internet import reactor twisted.internet.protocol import factory 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): session in self.sessions: if session not skip: session.send(line) reactor.listentcp(port, chatserver()) reactor.run()
Comments
Post a Comment