Esempio n. 1
0
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
Esempio n. 2
0
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)
Esempio n. 3
0
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)