天天看點

python與html5搭建聊天室_怎麼用python寫一個聊天室

展開全部

1.伺服器類62616964757a686964616fe78988e69d8331333361316566

首先需要一個聊天伺服器,這裡繼承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: %s\n' % 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

5.伺服器端完整代碼

#!/usr/bin/python

# encoding: utf-8

from asyncore import dispatcher

from asynchat import async_chat

import socket, asyncore

PORT = 6666 #端口

class EndSession(Exception):

"""

自定義會話結束時的異常

"""

pass

class CommandHandler:

"""

指令處理類

"""

def unknown(self, session, cmd):

'響應未知指令'

session.push('Unknown command: %s\n' % 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)

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

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))

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)

if __name__ == '__main__':

s = ChatServer(PORT)

try:

asyncore.loop()

except KeyboardInterrupt:

print

python與html5搭建聊天室_怎麼用python寫一個聊天室

已贊過

已踩過<

你對這個回答的評價是?

評論

收起