Red de conocimiento informático - Material del sitio web - Cómo escribir una sala de chat en Python

Cómo escribir una sala de chat en Python

1. Introducción al curso

1. Introducción

Esta clase de proyecto es para implementar el servidor y el cliente de un programa de sala de chat simple.

2. Puntos de conocimiento

El lado del servidor involucra los módulos de asyncore, asynchat y socket, y el cliente usa los módulos de telnetlib, wx, time y thread.

3. Entorno requerido

Se requiere WxPython para escribir el cliente en esta lección. Es un kit de herramientas GUI para instalarlo primero:

<. p>$ sudo apt-get install python-wxtools

La contraseña es shiyanlou

4. Captura de pantalla del efecto del proyecto

Ventana de inicio de sesión

Ventana de chat

2. Proyecto de combate real (lado del servidor)

1. Clase de servidor

Primero necesitas un servidor de chat, que se implementa aquí por heredando la clase de despachador de asyncore. El código es el siguiente

clase ChatServer(dispatcher):

"""

Servidor de chat

"""

def __init__(self, puerto):

dispatcher.__init__(self)

self.create_socket(socket.AF_INET, socket.SOCK_STREAM )

self.set_reuse_addr()

self.bind(('', puerto))

self.listen(5)

self.users = {}

self.main_room = ChatRoom(self)

def handle_accept(self):

conn, addr = self.accept( )

ChatSession( self, conn)

2. Clase de sesión

Con la clase de servidor, también es necesario mantener la sesión de conexión de cada usuario. Esto se implementa heredando la clase async_chat de asynchat. El código es el siguiente:

clase ChatSession(async_chat):

"""

Responsable de la comunicación. con usuarios únicos

"""

def __init__(self, server, sock):

async_chat.__init__(self, sock)

self.server = servidor

self.set_terminator(' \n')

self.data = []

self.name = Ninguno

self.enter(LoginRoom(server))

def enter(self, room):

'Eliminar self de la sala actual y luego agregarlo a la habitación especificada. room'

prueba:

cur = self .room

excepto AttributeError:

pass

otro:

cur.remove(self)

self .room = room

room.add(self)

def recolectar_incoming_data(self, data):

'Aceptar datos del cliente'

self.data.append(data)

def found_terminator(self):

'Procesamiento cuando finaliza un dato del cliente'

line = ''.join(self.data)

self.data = []

prueba:

self.room.handle(self, line)

e

xcept EndSession:

self.handle_close()

def handle_close(self):

async_chat.handle_close(self)

self. enter(LogoutRoom(self.server))

3. Intérprete de comandos

Ahora necesita un intérprete de comandos que pueda interpretar comandos de usuario, como iniciar sesión, consultar usuarios en línea y enviar. mensajes Espera, el código es el siguiente:

clase CommandHandler:

"""

Clase de procesamiento de comandos

"""

def desconocido(self, sesión, cmd):

'Respuesta a comando desconocido'

session.push('Comando desconocido: %s\n' % cmd)

def handle(self, session, line):

'Procesamiento de comandos'

si no line.strip():

regresar

partes = line.split(' ', 1)

cmd = partes[0]

prueba:

línea = partes[1 ].strip()

IndexError:

línea = ''

meth = getattr(self, 'do_' + cmd, Ninguno )

intenta:

meth(sesión, línea)

excepto TypeError:

self.unknown(sesión, cmd)

4. Sala

A continuación, necesitamos implementar la sala de chat. Aquí definimos tres tipos de salas, a saber, la sala cuando el usuario inicia sesión por primera vez, la sala de chat y la sala cuando. el usuario cierra sesión en estas tres salas. Cada sala tiene una clase principal pública, el código es el siguiente:

class Room(CommandHandler):

"""

<. p>Contiene un entorno de múltiples usuarios, responsable del procesamiento y transmisión de comandos básicos

"""

def __init__(self, server):

self.server = server

self.sessions = []

def add(self, session):

'Un usuario entra a la sala'

self.sessions.append (sesión)

def remove(self, sesión):

'Un usuario sale de la sala'

self.sessions.remove( session)

def broadcast(self, line):

'Enviar mensaje especificado a todos los usuarios'

para la sesión en self.sessions:

session. push(line)

def do_logout(self, session, line):

'Salir de la sala'

raise EndSession

clase LoginRoom (Sala):

"""

La sala del usuario que acaba de iniciar sesión

"""

def add(self, session ):

'Respuesta para conexión de usuario exitosa'

Room.a

dd(self, session)

session.push('Connect Success')

def do_login(self, session, line):

'Procesamiento del comando de inicio de sesión '

nombre = line.strip()

si no nombre:

session.push('Nombre de usuario vacío')

elif nombre en self.server.users:

session.push('UserName Exist')

otro:

session.name = nombre

session.enter(self.server.main_room)

clase ChatRoom(Sala):

"""

Sala de chat

"""

def add(self, session):

'Transmitir entrada de nuevo usuario'

session.push('Inicio de sesión exitoso')

self.broadcast(session.name + 'ha entrado a la sala.\n')

self.server.users[session.name] = sesión

Sala .add(self, session)

def remove(self, session):

'Transmitir al usuario para que abandone'

Room.remove(self, session)

self.broadcast(session.name + ' ha abandonado la sala.\n')

def do_say(self, session, line):

' El cliente envía mensaje'

self.broadcast(session.name + ': ' + línea + '\n')

def do_look(self, session, line):

'Ver usuarios en línea'

session.push('Usuarios en línea:\n')

para otros en self.sessions:

sesión .push(other.name + '\n')

clase LogoutRoom(Room):

"""

La sala cuando el usuario sale

p>

"""

def add(self, session):

'Eliminar del servidor'

intenta:

del self.server.users[session.name]

excepto KeyError:

pass

5. Código completo del lado del servidor

#!/usr/bin/python

# codificación: utf-8

desde asyncore import despachador

desde asynchat import async_chat

importar socket, asyncore

PORT = 6666 #Port

clase EndSession(Exception):

"""

Sesión autodefinida

Excepción al final

"""

pasar

clase CommandHandler:

"""

Comando Clase de procesamiento

"""

def desconocido(self, sesión, cmd):

'Respuesta a comando desconocido'

sesión push('Comando desconocido: %s\n' % cmd)

def handle(self, session, line):

'Procesamiento de comandos'

si no, line.strip():

retorno

partes = line.split(' ', 1)

cmd = partes[0]

pruebe:

línea = partes[1].strip()

excepto IndexError:

línea = ''

meth = getattr(self, 'do_' + cmd, Ninguno)

prueba:

meth(sesión, línea)

excepto TypeError:

self.unknown(session, cmd)

class Room(CommandHandler):

"""

Un entorno que contiene múltiples usuarios, responsable de Procesamiento y transmisión de comandos básicos

"""

def __init__(self, server):

self.server = server

self .sessions = []

def add(self, session):

'Un usuario entra a la sala'

self.sessions.append(session)< / p>

def remove(self, session):

'Un usuario abandona la sala'

self.sessions.remove(sesión)

def broadcast (self, line):

'Enviar mensaje especificado a todos los usuarios'

para la sesión en self.sessions:

session.push(line)

def do_logout(self, session, line):

'Salir de la sala'

levantar EndSession

clase LoginRoom(Sala) :

"""

La sala del usuario que acaba de iniciar sesión

"""

def add(self, session ):

'Respuesta a la conexión exitosa del usuario'

Room.add(self, session)

session.push('Connect Success')

def do_login(self, session, line):

'Procesamiento del comando de inicio de sesión'

nombre = line.strip()

si no es nombre :

session.push('Nombre de usuario vacío')

nombre elif en self.server.users:

session.push('Nombre de usuario existe')

más:

session.name = nombre

session.enter(self.server.main_room)

clase ChatRoom(Sala):

"""

Sala de chat

"""

def add(self, session):

'Transmitir nuevos usuarios para ingresar'

session.push('Inicio de sesión exitoso')

self.broadcast(session.name + ' ha ingresado a la sala.\n')

self.server.users [ session.name] = session

Room.add(self, session)

def remove(self, session):

'Transmitir usuario para que se vaya'

Room.remove(self, session)

self.broadcast(session.name + ' ha abandonado la habitación.\n')

def do_say(self , sesión, línea):

'Cliente envía mensaje'

self.broadcast(session.name + ':' + línea + '\n')

def do_look(self, session, line):

'Ver usuarios en línea'

session.push('Usuarios en línea:\n')

para otro en self.sessions:

session.push(other.name + '\n')

clase LogoutRoom(Room):

"""

La sala cuando el usuario sale

"""

def add(self, session):

'Eliminar del servidor '

intenta:

del self.server.users[session.name]

excepto KeyError:

pass

clase ChatSession(async_chat):

"""

Responsable de comunicarse con un solo usuario

"""

def __init__ (self, servidor, calcetín):

async_chat.__init__(self, calcetín)

self.server = servidor

self.set_terminator('\n ' )

self.data = []

self.name = Ninguno

self.enter(LoginRoom(servidor))

def enter(self, room):

'Eliminar self de la habitación actual y luego agregarlo a la habitación especificada'

try:

cur = self .room

excepto AttributeError:

pasar

otro:

cur.remove(self)

self .habitación = habitación

habitación.add(self)

def recopilar_datos_entrantes(sel

f, datos):

'Aceptar datos del cliente'

self.data.append(data)

def found_terminator(self):

'Procesamiento cuando finaliza un dato del cliente'

line = ''.join(self.data)

self.data = []

intenta:

self.room.handle(self, line)

excepto EndSession:

self.handle_close()

def handle_close(self):

async_chat.handle_close(self)

self.enter(LogoutRoom(self.server))

clase ChatServer(dispatcher):

"""

Servidor de chat

"""

def __init__(self, puerto):

dispatcher.__init__(self)

self.create_socket(socket.AF_INET, socket.SOCK_STREAM)

self.set_reuse_addr()

self.bind(( ( '', puerto))

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)

prueba:

asyncore.loop()

excepto KeyboardInterrupt:

p>

imprimir

3. Proyecto de combate real (cliente)

Después de completar el lado del servidor, debe implementar el cliente. Aquí el cliente usa telnetlib. Módulo para conectarse al servidor.

1. Ventana de inicio de sesión

El paquete de interfaz gráfica aquí usa wxPython. Hay instrucciones de instalación al frente. La ventana de inicio de sesión se implementa heredando la clase wx.Frame. siguiente:

clase LoginFrame(wx.Frame):

"""

Ventana de inicio de sesión