class Server(object): """服务器核心类""" def __init__(self): # 创建服务器套接字 self.server_socket = ServerSocket() # 创建请求的id和方法关联字典 self.request_handle_function = {} self.register(REQUEST_LOGIN, self.request_login_handle) self.register(REQUEST_CHAT, self.request_chat_handle) self.register(REQUEST_SIGN_UP, self.request_sign_up_handle) # 创建保存当前用户登录字典 self.clients = {} # 创建数据库管理对象 self.db = DB() def register(self, request_id, handle_function): # 注册消息类型和处理函数到字典 self.request_handle_function[request_id] = handle_function def startup(self): """获取客户端连接,提供服务""" while True: # 获取客户端连接 print('正在获取客户端连接') soc, addr = self.server_socket.accept() print('获取到客户端连接') # 使用套接字生成包装对象 client_soc = SocketWrapper(soc) # 收发消息 t = Thread(target=self.request_handle, args=(client_soc, )) t.start() def request_handle(self, client_soc): """处理客户端请求""" while True: recv_data = client_soc.recv_data() if not recv_data: self.remove_office_user(client_soc) client_soc.close() break print(recv_data) # 解析数据 parse_data = self.parse_request_text(recv_data) # 分析请求类型,并根据类型调用相应函数 handle_function = self.request_handle_function.get( parse_data['request_id']) if handle_function: handle_function(client_soc, parse_data) def remove_office_user(self, client_soc): # 客户端下线处理 print('有客户端下线了') for username, info in self.clients.items(): if info['sock'] == client_soc: print(self.clients) del self.clients[username] print(self.clients) break def parse_request_text(self, text): """" 解析客户端发送来的数据 登录信息:0001|username|password 聊天信息:0002|username|messages 注册信息:0003|username|password|nickname """ print('解析客户端数据:' + text) request_list = text.split(DELIMITER) # 按照类型解析数据 request_data = {} request_data['request_id'] = request_list[0] if request_data['request_id'] == REQUEST_LOGIN: # 用户登录信息 request_data['username'] = request_list[1] request_data['password'] = request_list[2] elif request_data['request_id'] == REQUEST_CHAT: # 用户聊天信息 request_data['username'] = request_list[1] request_data['messages'] = request_list[2] elif request_data['request_id'] == REQUEST_SIGN_UP: # 用户注册信息 request_data['username'] = request_list[1] request_data['password'] = request_list[2] request_data['nickname'] = request_list[3] return request_data def request_chat_handle(self, client_soc, request_data): # 处理聊天功能 print('收到聊天信息。。。准备处理', request_data) # 获取消息内容 username = request_data['username'] messages = request_data['messages'] nickname = self.clients[username]['nickname'] # 拼接发送给客户端的消息文本 msg = ResponseProtocol.response_chat(nickname, messages) # 转发给在线用户 for u_name, info in self.clients.items(): if username == u_name: # 不需要向发送消息的账号转发消息 continue info['sock'].send_data(msg) def request_sign_up_handle(self, client_soc, request_data): # 处理注册功能 print('收到注册请求。。。准备处理') # 获取密码 username = request_data['username'] password = request_data['password'] nickname = request_data['nickname'] # 检查是否能够注册 ret, username, nickname = self.check_user_sign_up(username, nickname) # 注册成功将当前用户信息插入数据库 if ret == '1': user_id = self.db.count_user() self.db.insert_user("insert into users values(%d,'%s','%s','%s')" % (user_id + 1, username, password, nickname)) # 拼接返回给客户端的信息 response_text = ResponseProtocol.response_sign_up( ret, username, nickname) # 发送信息给客户端 client_soc.send_data(response_text) def request_login_handle(self, client_soc, request_data): # 处理登录功能 print('收到登录请求。。。准备处理') # 获取账号密码 username = request_data['username'] password = request_data['password'] # 检查是否能够登录 ret, nickname, username = self.check_user_login(username, password) # 登录成功保存当前用户 if ret == '1': self.clients[username] = {'sock': client_soc, 'nickname': nickname} # 拼接返回给客户端的消息 response_text = ResponseProtocol.response_login_result( ret, nickname, username) # 把消息发送给客户端 client_soc.send_data(response_text) def check_user_login(self, username, password): """检查用户是否登录成功,并返回检查结果(0/失败,1/成功),昵称,用户名""" # 从数据库查询用户信息 result = self.db.get_one("select * from users where user_name='%s'" % username) # 没有查询结果则说明用户不存在,登录失败 if not result: return '0', '', username # 如果密码不匹配,说明密码错误,登陆失败 if password != result['user_password']: return '0', '', username # 登录成功 return '1', result['user_nickname'], username def check_user_sign_up(self, username, nickname): """检查用户是否注册成功,并返回检查结果(0/失败,1/成功),昵称,用户名""" # 从数据库查询用户信息 username_result = self.db.search_one( "select * from users where user_name='%s'" % username) nickname_result = self.db.search_one( "select * from users where user_nickname='%s'" % nickname) # 有相同账号则注册失败 if username_result: return '0', username, '' # 有相同昵称则注册失败 elif nickname_result: return '0', '', nickname # 注册成功 return '1', username, nickname
class Server(object): """服务器""" def __init__(self): # 初始化套接字 self.server_socket = ServerSocket() # 保存客户端连接套接字 self.clients = dict() # 请求处理方法 self.request_handle_functions = dict() # 注册请求处理方法 self.register(REQUEST_LOGIN, lambda sf, data: self.request_login_handle(sf, data)) self.register(REQUEST_CHAT, lambda sf, data: self.request_chat_handle(sf, data)) def register(self, request_id, handle_function): """注册请求处方法""" self.request_handle_functions[request_id] = handle_function def startup(self): """启动服务器""" while True: # 等待客户端连接 sock, addr = self.server_socket.accept() # 给客户端sock 增加额外功能 client_sock = SocketWrapper(sock) # 启动线程处理该用户请求 Thread(target=lambda: self.request_handle(client_sock)).start() def request_handle(self, client_sock): """响应处理方法""" while True: # 1.读取客户端数据 request_text = client_sock.recv_data() if not request_text: print("客户端下线!") self.remove_offline_user(client_sock) break # 2.解析请求数据 request_data = self.parse_request_text(request_text) # 3.获取响应处理方法 handle_function = self.request_handle_functions[ request_data['request_id']] # 4.执行响应处理方法 if handle_function: handle_function(client_sock, request_data) def remove_offline_user(self, client_sock): """移除离线用户连接""" username = None for uname, csock in self.clients.items(): if csock['sock'].sock == client_sock.sock: username = uname # 删除用户信息 del self.clients[username] @staticmethod def parse_request_text(request_text): """解析请求信息""" request_text_list = request_text.split(DELIMITER) # 保存请求数据 request_data = dict() request_data['request_id'] = request_text_list[0] if request_text_list[0] == REQUEST_LOGIN: request_data['username'] = request_text_list[1] request_data['password'] = request_text_list[2] if request_text_list[0] == REQUEST_CHAT: request_data['username'] = request_text_list[1] request_data['password'] = request_text_list[2] return request_data def request_login_handle(self, client_sock, request_data): """处理用户登录""" # 1.获得登录用户名和密码 username = request_data['username'] password = request_data['password'] # 2.验证用户是否合法 ret, nickname, username = self.check_user_login(username, password) if ret == '1': self.clients[username] = { 'sock': client_sock, 'nickname': nickname } # 4.组装响应结果 response_text = ResponseProtocol.response_login_result( ret, nickname, username) # 发送响应结果 client_sock.send_data(response_text) def check_user_login(self, username, password): """用户名和密码验证""" # 查询sql sql = "select * from users where user_name='" + username + "'" # 创建数据库连接对象 db_conn = DB() results = db_conn.get_one(sql) # 未查到数据 if not results: return "0", "", username # 用户名和密码不相等 if results['user_password'] != password: return "0", "", username return "|", results["user_nickname"], username def request_chat_handle(self, client_sock, request_data): """处理用户聊天""" # 1.获得当前用户名、发送信息、昵称 username = request_data['username'] messages = request_data['messages'] nickname = self.clients[username]['nickname'] # 创建聊天响应信息 response_text = ResponseProtocol.response_chat(nickname, messages) # 2.将信息发送到每一个登录客户 for uname, csock in self.clients.items(): # 不发给自己 if uname == username: continue # 给其他用户发送信息 csock['sock'].send_data(response_text)
class Server(object): def __init__(self): self.server_socket = ServerSocket() #request id and its corresponding handler function self.req_handler_functions = {} self.register(REQUEST_LOGIN, self.request_login_handler) self.register(REQUEST_CHAT, self.request_chat_handler) #save info of logged in user self.clients = {} #init db self.db = DB() def register(self, req_id, handler): #for each req type, register handler for it a dictionary self.req_handler_functions[req_id] = handler def startup(self): """accept connection from client""" while True: print('waiting connection from client...') soc, addr = self.server_socket.accept() print('Accepted connection from client') client_soc = SocketWrapper(soc) Thread(target=lambda: self.request_handler(client_soc)).start() def request_handler(self, client_soc): """handle client requests""" while True: #receive and send data recv_data = client_soc.recv_data() #receiving nothing means user left if not recv_data: self.remove_offline_user(client_soc) client_soc.close() break #get request type and call corresponding handler handler_function = self.req_handler_functions.get(recv_data['type']) if handler_function: handler_function(client_soc, recv_data) def remove_offline_user(self, client_soc): print('user left') for username, info in self.clients.items(): if info['soc'] == client_soc: print(self.clients) del self.clients[username] print(self.clients) break def request_login_handler(self, client_soc, req_data): print('received longin req, processing') #obtain username and pwd username = req_data['username'] pwd = req_data['pwd'] #check credentials result, username = self.check_credential(username, pwd) #existing user=>save user info if result == '1': print('client soc') print(client_soc) self.clients[username] = {'soc': client_soc} #generate response response_text = ResponseProtocol.response_login(result, username) #response to user whether login succeeded or not client_soc.send_data(response_text) def check_credential(self, username, pwd): """ check if the given user existed result: 0: no such a user 1: user is existing return (result, username) """ print('checking user credentials') result = self.db.get_user(username, pwd) if not result: return '0','' return '1', result['user_name'] def request_chat_handler(self, client_soc, req_data): print('received chat req, processing') #get message content username = req_data['username'] msg = req_data['msg'] #TODO: publish to pub/sub middleware? #generate response response_text = ResponseProtocol.response_chat(username, msg) #send response to users for u_name, info in self.clients.items(): if username == u_name: continue info['soc'].send_data(response_text) print(req_data)