如何用Python编写一个聊天室

 我来答
就烦条0o
推荐于2016-05-29 · 知道合伙人软件行家
就烦条0o
知道合伙人软件行家
采纳数:33315 获赞数:46492
从事多年系统运维,喜欢编写各种小程序和脚本。

向TA提问 私信TA
展开全部
  1.服务器类
  首先需要一个聊天服务器,这里继承asyncore的dispatcher类来实现,代码如下

  class ChatServer(dispatcher):
  """
  聊天服务器
  """

  def __init__(self, port):
  dispatcher.__init__(self)
  self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
  self.set_reuse_addr()
  self.bind(('', port))
  self.listen(5)
  self.users = {}
  self.main_room = ChatRoom(self)

  def handle_accept(self):
  conn, addr = self.accept()
  ChatSession(self, conn)
  2.会话类
  有了服务器类还需要能维护每个用户的连接会话,这里继承asynchat的async_chat类来实现,代码如下:

  class ChatSession(async_chat):
  """
  负责和单用户通信
  """

  def __init__(self, server, sock):
  async_chat.__init__(self, sock)
  self.server = server
  self.set_terminator('n')
  self.data = []
  self.name = None
  self.enter(LoginRoom(server))

  def enter(self, room):
  '从当前房间移除自身,然后添加到指定房间'
  try:
  cur = self.room
  except AttributeError:
  pass
  else:
  cur.remove(self)
  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))
  3.命令解释器
  现在就需要一个命令解释器能够解释用户的命令,例如登录、查询在线用户和发消息等,代码如下:

  class CommandHandler:
  """
  命令处理类
  """

  def unknown(self, session, cmd):
  '响应未知命令'
  session.push('Unknown command: %sn' % cmd)

  def handle(self, session, line):
  '命令处理'
  if not line.strip():
  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)
  4.房间
  接下来就需要实现聊天室的房间了,这里我们定义了三种房间,分别是用户刚登录时的房间、聊天的房间和退出登录的房间,这三种房间都有一个公共的父类,代码如下:

  class Room(CommandHandler):
  """
  包含多个用户的环境,负责基本的命令处理和广播
  """

  def __init__(self, server):
  self.server = server
  self.sessions = []

  def add(self, session):
  '一个用户进入房间'
  self.sessions.append(session)

  def remove(self, session):
  '一个用户离开房间'
  self.sessions.remove(session)

  def broadcast(self, 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)
  session.push('Connect Success')

  def do_login(self, session, line):
  '登录命令处理'
  name = line.strip()
  if not name:
  session.push('UserName Empty')
  elif name in self.server.users:
  session.push('UserName Exist')
  else:
  session.name = name
  session.enter(self.server.main_room)

  class ChatRoom(Room):
  """
  聊天用的房间
  """

  def add(self, session):
  '广播新用户进入'
  session.push('Login Success')
  self.broadcast(session.name + ' has entered the room.n')
  self.server.users[session.name] = session
  Room.add(self, session)

  def remove(self, session):
  '广播用户离开'
  Room.remove(self, session)
  self.broadcast(session.name + ' has left the room.n')

  def do_say(self, session, line):
  '客户端发送消息'
  self.broadcast(session.name + ': ' + line + 'n')

  def do_look(self, session, line):
  '查看在线用户'
  session.push('Online Users:n')
  for other in self.sessions:
  session.push(other.name + 'n')

  class LogoutRoom(Room):
  """
  用户退出时的房间
  """

  def add(self, session):
  '从服务器中移除'
  try:
  del self.server.users[session.name]
  except KeyError:
  pass
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式