- 论坛徽章:
- 0
|
本帖最后由 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[0]
- try:
- line = parts[1].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.name] = 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[session.name]
- 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'
复制代码 |
|