python小菜 发表于 2014-08-12 11:48

如何把《python基础编程》的24章虚拟茶话会改成多房间的?

本帖最后由 python小菜 于 2014-08-12 12:56 编辑

如题!!求各位大牛指导,或者给点思路#coding:utf-8
from asyncore import dispatcher
from asynchat import async_chat
import socket
import asyncore

HOST = ''
PORT = 50005
SERVERCONF = (HOST,PORT)
NAME = 'TestChat'

class EndSession(Exception):
    pass

class CommandHandler(object):
    '''''
    命令解析类
    '''
   
    def unknown(self,session,cmd):
      '响应未知的命令'
      session.push('Unknown command: %s \r\n' %cmd)

    def handle(self,session,line):
      '处理从客户端发来的信息 解析命令和内容'
            
      if not line.strip():
            print 'get a line :',line
            return
         
      parts = line.split(' ',1)
      #命令分离
      cmd = parts
      try:
            line = parts.strip()
      except IndexError:
            line = ''
      #调用相应的方法处理命令
      meth = getattr(self, 'do_'+cmd, None)
      try:
            #调用命令对应的方法
            meth(session,line)
      except TypeError:
            self.unknown(session, cmd)
            
class Room(CommandHandler):
    '''''
    包括一个或多个用户(会话)的泛型环境。负责处理基本的命令和广播
    '''
   
    def __init__(self,server):
      self.server = server
      self.sessions = []
         
    def add(self, session):
      'add a user'
      self.sessions.append(session)
         
    def remove(self,session):
      'a user leave'
      self.sessions.remove(session)
         
    def broadcast(self,line):
      'give all session in the room a line'
      for session in self.sessions:
            session.push(line)
         
    def do_logout(self,session,line):
      '响应登出命令'
      raise EndSession
   
class LoginRoom(Room):
    '''''
    为刚刚登陆的用户准备的房间
    '''
   
    def add(self,session):
      Room.add(self, session)
      self.broadcast('Welcome to %s \r\n' %self.server.name)
         
    def unknown(self, session, cmd):
      session.push('Please login \nUse "login <nick>"\r\n')
         
    def do_login(self, session, line):
      name = line.strip()
      #登陆时必须指定一个用户名
      if not name:
            session.push('Please enter a name\r\n')
      elif name in self.server.users: #用户名不可重复 ?
            session.push('The name "%s" is taken! \r\n' %name)
            session.push('Please try again.\r\n')
      else:
            session.name = name
            session.enter(self.server.main_room)
            
class ChatRoom(Room):
    '''''
    为多用户在一起聊天准备的房间
    '''
    def add(self, session):
      #tell all new one come
      self.broadcast(session.name +' has entered the room. \r\n')
      self.server.users = session
      Room.add(self, session)
         
    def remove(self, session):
      Room.remove(self. session)
      #tell all the user logout
      self.broadcast(session.name +' has left the room \r\n')
         
    def do_say(self, session, line):
      self.broadcast(session.name+': '+line+'\r\n')
         
    def do_look(self, session, line):
      'look who is in the room'
      session.push('The following are in this room: \r\n')
      for other in self.sessions:
            session.push(other.name+'\r\n')
            
    def do_who(self, session, line):
      '查看谁登陆过'
      session.push('The following are logged in: \r\n')
      for name in self.server.users:
            session.push(name+ '\r\n')

class LogoutRoom(Room):
    '''''
    为单个用户准备的房间,只用于将用户从服务器移除
    '''
   
    def add(self, session):
      try:
            del self.server.users
      except KeyError:
            pass
         
class ChatSession(async_chat):
    '''''
    单个会话,负责和用户通信
    '''
   
    def __init__(self, server, sock):
      async_chat.__init__(self, sock)
      self.server = server
      self.set_terminator('\r\n')
      self.data = []
      self.name = None
      #所有会话从这里登入
      self.enter(LoginRoom(server))

    def enter(self, room):
      try:
            cur = self.room
      except AttributeError:
            pass
      self.room = room
      room.add(self)
         
    def collect_incoming_data(self, data):
      self.data.append(data)
         
    def found_terminator(self):
      line = ''.join(self.data)
      self.data = []
      try:
            self.room.handle(self, line)
      except EndSession:
            self.handle_close()
         
    def handle_close(self):
      async_chat.handle_close(self)
      self.enter(LogoutRoom(self.server))
         
class ChatServer(dispatcher):
    '''''
    只有一个房间的聊天服务器
    '''
   
    def __init__(self, serverconf, name):
      dispatcher.__init__(self)
      self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
      self.set_reuse_addr() #可以重用上一次的端口号
      self.bind(SERVERCONF)
      self.listen(5)
      self.name = name
      self.users = {}
      self.main_room = ChatRoom(self)
   
    def handle_accept(self):
      conn, addr = self.accept()
      ChatSession(self, conn)

#主函数      
if __name__=='__main__':
    s = ChatServer(SERVERCONF,NAME)
    try:
      asyncore.loop()
    except KeyboardInterrupt:
      print 'server Exception ...quit'

ssfjhh 发表于 2014-08-12 12:47

同学,你至少把题目抄过来呗,那本书不是谁都有,而且谁有功夫帮你翻书?

python小菜 发表于 2014-08-12 12:57

回复 2# ssfjhh

不好意思。。。代码已经贴上去啦!
   

ssfjhh 发表于 2014-08-12 13:57

回复 3# python小菜


    同学,给你跪了。

python小菜 发表于 2014-08-12 14:33

。。。难道还有问题!!这个程序只是一个房间的聊天,现在想改成多房间聊天,不知道如何下手回复 4# ssfjhh


   

python小菜 发表于 2014-08-13 12:31

大牛快出现啊~不要沉了

Linux_manne 发表于 2014-08-14 14:46

多房间聊天? 没明白

python小菜 发表于 2014-08-15 18:52

源程序就是只能在一个房间里面聊天,而我想把它改成多个房间,就是新来的用户可以选择创建一个房间,或者加入其他存在的房间!回复 7# Linux_manne


   

pitonas 发表于 2014-08-16 11:49

在不同房间里面聊天?
一个房聊 不好?
页: [1]
查看完整版本: 如何把《python基础编程》的24章虚拟茶话会改成多房间的?