예제 #1
0
def run(sc, parameters):
    # pprint(parameters)
    user_id = sc_to_user_id[sc]
    sender = database.get_user(user_id)

    # target_id在后面填入,对于发送方和接收方不一样
    message = {
        "message": parameters['message'],
        'sender_id': user_id,
        'sender_name': sender['username'],
        'target_type': parameters['target_type'],
        'time': int(round(time.time() * 1000))
    }

    if parameters['target_type'] == 0:
        # 私聊
        if not database.is_friend_with(user_id, parameters['target_id']):
            sc.send(MessageType.general_failure, '还不是好友')
            return

        # 给发送方发回执
        message['target_id'] = parameters['target_id']
        user_id_to_sc[user_id].send(MessageType.on_new_message, message)
        database.add_to_chat_history(user_id, message['target_id'],
                                     message['target_type'],
                                     _serialize_dict(message), True)

        # 给接收方发消息,存入聊天记录
        message['target_id'] = user_id
        sent = False
        if parameters['target_id'] in user_id_to_sc:
            sent = True
            user_id_to_sc[parameters['target_id']].send(
                MessageType.on_new_message, message)

        database.add_to_chat_history(parameters['target_id'],
                                     message['target_id'],
                                     message['target_type'],
                                     _serialize_dict(message), sent)

    if parameters['target_type'] == 1:
        # 群聊
        message['target_id'] = parameters['target_id']

        if not database.in_room(user_id, parameters['target_id']):
            sc.send(MessageType.general_failure, '还没有加入该群')
            return

        users_id = database.get_room_members_id(parameters['target_id'])

        for user_id in users_id:
            sent = False
            if user_id in user_id_to_sc:
                user_id_to_sc[user_id].send(MessageType.on_new_message,
                                            message)
                sent = True

            database.add_to_chat_history(user_id, message['target_id'],
                                         message['target_type'],
                                         _serialize_dict(message), sent)
예제 #2
0
def run():
    gen_cert()

    config = get_config()
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((config['server']['bind_ip'], config['server']['bind_port']))
    s.listen(1)

    print("Server listening on " + config['server']['bind_ip'] + ":" + str(config['server']['bind_port']))

    bytes_to_receive = {}
    bytes_received = {}
    data_buffer = {}

    while True:
        rlist, wlist, xlist = select.select(list(map(lambda x: x.socket, scs)) + [s], [], [])

        for i in rlist:

            if i == s:
                # 监听socket为readable,说明有新的客户要连入
                sc = common.transmission. 	secure_channel.accept_client_to_secure_channel(s)
                socket_to_sc[sc.socket] = sc
                scs.append(sc)
                bytes_to_receive[sc] = 0
                bytes_received[sc] = 0
                data_buffer[sc] = bytes()
                continue

            # 如果不是监听socket,就是旧的客户发消息过来了
            sc = socket_to_sc[i]

            if bytes_to_receive[sc] == 0 and bytes_received[sc] == 0:
                # 一次新的接收
                conn_ok = True
                first_4_bytes = ''
                try:
                    first_4_bytes = sc.socket.recv(4)
                except ConnectionError:
                    conn_ok = False

                if first_4_bytes == "" or len(first_4_bytes) < 4:
                    conn_ok = False

                if not conn_ok:
                    sc.close()

                    if sc in sc_to_user_id:
                        user_id = sc_to_user_id[sc]
                        # 通知他的好友他下线了

                        frs = database.get_friends(user_id)
                        for fr in frs:
                            if fr['id'] in user_id_to_sc:
                                user_id_to_sc[fr['id']].send(MessageType.friend_on_off_line, [False, user_id])

                        # 通知群聊里的人
                        # [room_id, user_id, online]
                        rooms_id = database.get_user_rooms_id(user_id)
                        for room_id in rooms_id:
                            users_id = database.get_room_members_id(room_id)
                            for _user_id in users_id:
                                if _user_id in user_id_to_sc and user_id != _user_id:
                                    user_id_to_sc[_user_id].send(MessageType.room_user_on_off_line,
                                                                 [room_id, user_id, False])

                    # 把他的连接信息移除
                    remove_sc_from_socket_mapping(sc)

                else:
                    data_buffer[sc] = bytes()
                    bytes_to_receive[sc] = struct.unpack('!L', first_4_bytes)[0] + 16 + 1 + 32

            buffer = sc.socket.recv(bytes_to_receive[sc] - bytes_received[sc])
            data_buffer[sc] += buffer
            bytes_received[sc] += len(buffer)

            if bytes_received[sc] == bytes_to_receive[sc] and bytes_received[sc] != 0:
                # 当一个数据包接收完毕
                bytes_to_receive[sc] = 0
                bytes_received[sc] = 0
                try:
                    data = sc.on_data(data_buffer[sc])
                    print(data['type'])
                    handle_event(sc, data['type'], data['parameters'])
                except:
                    pprint(sys.exc_info())
                    traceback.print_exc(file=sys.stdout)
                    pass
                data_buffer[sc] = bytes()
예제 #3
0
def run(sc, parameters):
    parameters[0] = parameters[0].strip().lower()
    c = database.get_cursor()
    sql = "SELECT id,username from users where username='******' and password='******'" % (
        parameters[0], md5(parameters[1]))
    print(sql)
    #r = c.execute("SELECT id,username from users where username='******' and password='******'", (parameters[0], md5(parameters[1])))
    c.execute(sql)
    rows = c.fetchall()

    if len(rows) == 0:
        sc.send(MessageType.login_failed)
        return

    user_id = rows[0][0]

    # 已经登入,踢下线
    if user_id in user_id_to_sc:
        sc_old = user_id_to_sc[user_id]
        sc_old.send(MessageType.server_kick)
        sc_old.close()
        remove_sc_from_socket_mapping(sc_old)

    sc_to_user_id[sc] = user_id
    user_id_to_sc[user_id] = sc
    user = database.get_user(user_id)
    sc.send(MessageType.login_successful, user)

    login_bundle = {}

    # 发送群列表
    rms = database.get_user_rooms(user_id)
    login_bundle['rooms'] = list(map(lambda x: add_target_type(x, 1), rms))

    # for rm in rms:
    #     sc.send(MessageType.contact_info, add_target_type(rm, 1))

    # 发送好友请求
    frs = database.get_pending_friend_request(user_id)

    for fr in frs:
        sc.send(MessageType.incoming_friend_request, fr)

    # 发送好友列表
    frs = database.get_friends(user_id)
    login_bundle['friends'] = list(map(lambda x: add_target_type(x, 0), frs))

    for fr in frs:
        # sc.send(MessageType.contact_info, add_target_type(fr, 0))
        # 通知他的好友他上线了
        if fr['id'] in user_id_to_sc:
            user_id_to_sc[fr['id']].send(MessageType.friend_on_off_line,
                                         [True, user_id])

    # 通知群聊里的人他上线了
    # [room_id, user_id, online]
    rooms_id = database.get_user_rooms_id(user_id)
    for room_id in rooms_id:
        users_id = database.get_room_members_id(room_id)
        for _user_id in users_id:
            if _user_id in user_id_to_sc and user_id != _user_id:
                user_id_to_sc[_user_id].send(MessageType.room_user_on_off_line,
                                             [room_id, user_id, True])

    login_bundle['messages'] = database.get_chat_history(user_id)
    sc.send(MessageType.login_bundle, login_bundle)