python之虚拟聊天室服务器详解

来源:互联网 发布:夜来风雨声花落知多少 编辑:程序博客网 时间:2024/05/16 12:43

这个虚拟聊天室 还是一个简单的服务器搭建的,运行截图大概是这样的


 



主要代码如下:

 

  1. '''''  
  2. Created on 2012-7-19  
  3.  
  4. @author: mars  
  5. ''' 
  6. from asyncore import dispatcher  
  7. from asynchat import async_chat  
  8. import socket,asyncore  
  9.  
  10. PORT=5006 
  11. NAME='TestChat2' 
  12.  
  13. class EndSession(Exception):pass 
  14.  
  15. class CommandHandler:  
  16.     def unknown(self,session,cmd):  
  17.         session.push('unknown command: %s\r\n'%cmd)  
  18.     def handle(self,session,line):  
  19.         #del the line from the target chat  
  20.         if not line.strip(): return 
  21.         parts=line.split(' ',1)  
  22.         cmd=parts[0]  
  23.         try:line=parts[1].strip()  
  24.         except IndexError: line='' 
  25.         #try to find the deal programe  
  26.         meth=getattr(self,'do_'+cmd,None)  
  27.         try:  
  28.             meth(session,line)  
  29.         except TypeError:  
  30.             self.unknown(session, cmd)  
  31. class Room(CommandHandler):  
  32.     #including more chat responsible boardcast and deal command  
  33.     def __init__(self,server):  
  34.         self.server=server  
  35.         self.sessions=[]  
  36.     def add(self,session):  
  37.         # one user into the room  
  38.         self.sessions.append(session)  
  39.     def remove(self,session):  
  40.         # one user out the room  
  41.         self.sessions.remove(session)  
  42.     def broadcast(self,line):  
  43.         # to evrytroom one line  
  44.         for session in self.sessions:  
  45.             session.push(line)  
  46.     def do_logout(self,session,line):  
  47.         #make the logout command  
  48.         raise EndSession  
  49. class LoginRoom(Room):  
  50.     #for the user have been connected now to prepare room  
  51.     def add(self,session):  
  52.         Room.add(self, session)  
  53.         #when user come to the room !!!welcome user  
  54.         self.broadcast("welcome to %s\r\n" % self.server.name)  
  55.     def unknown(self,session,cmd):  
  56.         #chul login and loginout can make an advice  
  57.         session.push('please log in\n Use"login<nick>"\r\n')  
  58.       
  59.     def remove(self,session):  
  60.         Room.remove(self, session)  
  61.         #Room.remove(self, session)  
  62.         self.broadcast(session.name+"has out the room.\r\n")     
  63.     def do_login(self,session,line):  
  64.         name=line.strip()  
  65.         if not name:  
  66.             session.push("please enter a name\r\n")  
  67.         elif name in self.server.users:  
  68.             session.push('the name"%s" is taken.\r\n'%name)  
  69.         else:  
  70.             session.name=name  
  71.             #print session.name  
  72.               
  73.             #print 'kkk'+name  
  74.             #session.enter(ChatRoom(self))  
  75.             session.enter(self.server.main_room)  
  76. class ChatRoom(Room):  
  77.     #multiuser chatroom  
  78.     def add(self,session):  
  79.         # tell all user  the newuset comein  
  80.         self.broadcast(session.name+"has ented the room.\r\n")  
  81.         self.server.users[session.name]=session  
  82.         Room.add(self, session)  
  83.     def do_say(self,session,line):  
  84.         self.broadcast(session.name+":"+line+'\r\n')  
  85.     def do_look(self,session,line):  
  86.         #check who is in the room  
  87.         session.push('the following in the room:\r\n')  
  88.         for other in self.sessions:  
  89.             session.push(other.name+'\r\n')  
  90.     def do_who(self,session,line):  
  91.         #to check who is logining   
  92.         session.push('the floowing is logining:\r\n')  
  93.         for name in self.server.users:  
  94.             session.push(name+'\r\n')  
  95. class LogoutRoom(Room):  
  96.     def add(self,session):  
  97.         try:  
  98.             del self.server.users[session.name]  
  99.         except KeyError:pass 
  100. class ChatSession(async_chat):  
  101.     #responsibel sigle user communicate  
  102.     def __init__(self,server,sock):  
  103.         async_chat.__init__(self,sock)  
  104.         self.server=server  
  105.         self.set_terminator("\r\n")  
  106.         self.data=[]  
  107.         self.name=None 
  108.         self.enter(LoginRoom(server))  
  109.     def enter(self,room):  
  110.         try:cur=self.room  
  111.         except AttributeError:pass 
  112.         else:cur.remove(self)  
  113.         self.room=room  
  114.         room.add(self)  
  115.     def collect_incoming_data(self,data):  
  116.         self.data.append(data)   
  117.     def found_terminator(self):  
  118.         line=''.join(self.data)  
  119.         self.data=[]  
  120.         try:  
  121.             self.room.handle(self,line)  
  122.         except EndSession:  
  123.             self.handle_close()  
  124.     def handle_close(self):  
  125.         async_chat.handle_close(self)  
  126.         self.enter(LogoutRoom(self.server))  
  127. class ChatServer(dispatcher):  
  128.     #only have one room for the chating 's server  
  129.     def __init__(self,port,name):  
  130.         dispatcher.__init__(self)  
  131.         #dispatcher.__init__(self)  
  132.         self.create_socket(socket.AF_INET,socket.SOCK_STREAM)  
  133.         self.set_reuse_addr()  
  134.         self.bind(('',port))  
  135.         self.listen(5)  
  136.         self.name=name  
  137.         self.users={}  
  138.         self.main_room=ChatRoom(self)  
  139.           
  140.     def handle_accept(self):  
  141.         conn,addr = self.accept()  
  142.         ChatSession(self,conn)  
  143. if __name__=="__main__":  
  144.     s=ChatServer(PORT,NAME)  
  145.     try:asyncore.loop()  
  146.     except KeyboardInterrupt: print   
  147.       
  148.     

现在我们开始来详细分析其中的代码,说道详细其实也不会细致到每一行代码,毕竟很多跟上一篇文章讲的一样,这里我们主要分析的是这个cmd的基础命令解释,你看最开始的那个截图,你会发现,login用户名为ni,然后输入say 你好,然后就有 ni:你好,而这个方法就是do_say();

  1. class CommandHandler:  
  2.     def unknown(self,session,cmd):  
  3.         session.push('unknown command: %s\r\n'%cmd)  
  4.     def handle(self,session,line):  
  5.         #del the line from the target chat  
  6.         if not line.strip(): return 
  7.         parts=line.split(' ',1)  
  8.         cmd=parts[0]  
  9.         try:line=parts[1].strip()  
  10.         except IndexError: line='' 
  11.         #try to find the deal programe  
  12.         meth=getattr(self,'do_'+cmd,None)  
  13.         try:  
  14.             meth(session,line)  
  15.         except TypeError:  
  16.             self.unknown(session, cmd) 

1,这个handle函数的作用:首先 你输入一个行,然后 parts = line.strip("  "   ,1)将行用空格将行断开成为一个个的,然后取里面的第一个也就是cmd = parts[0],就如刚刚的截图所看到的一样say就被取出来作为cmd了。然后 再仔细观察下面的getattr是不是似曾相识,对的 就在第一篇文本标记的时候讲过的,这个其实很好用,前面是“do_”+cmd(而cmd就是你输入的指令)这样的话,就可以完成了!这当然这是基础命令解释。

2,接下来就是Room了,功能很简单,基础类Room继承了CommandHanlder,包括一个或者多个用户会话的环境,主要负责基本命令处理,和广播。LoginRoom继承Room,为刚刚连接上的用户准备的房间,LogoutRoom用于将用户从服务器移除。ChatRoom就是多用户聊天的地方了 ,一旦登陆进去就到这儿了。ChatSession和ChatServer就不多说 在前面一篇文章已经说过了,

本文出自 “LuoZhengWu” 博客,请务必保留此出处http://brucemars.blog.51cto.com/5288106/962319

0 0