예제 #1
0
def user_controls_cmd(sock, user_name):
    """
    Обработчик поступающих команд от клиента
    :param sock: клиентский сокет
    :param user_name: имя текущего клиента
    :return:
    """
    print(
        'Команда \'message\' для ввода и отправки сообщения, \'exit\' для завершения работы: '
    )

    while True:
        command = input('Введите команду: ')
        if command == 'message':
            create_client_msg(sock, user_name)
        elif command == 'exit':
            send_message(sock, create_exit_message(user_name))
            client_logger.info('Завершение работы по команде пользователя')
            print('*** Завершение работы ***')
            time.sleep(0.5)
            break
        else:
            print(
                'Команда не распознана, попробуйте снова. \n'
                'Команда \'message\' для ввода и отправки сообщения, \'exit\' для завершения работы: '
            )
예제 #2
0
def create_client_msg(sock, account_name):
    """
    Формирование и отправка на сервер сообщения клиента
    :param sock: клиентский сокет
    :param account_name: строка псевдонима
    :return message_dict: словарь сообщения клиента
    """

    receiver_name = input('Введите получателя сообщения: ')
    message_str = input('Введите сообщение для отправки: ')

    message_dict = {
        ACTION: MESSAGE,
        TIME: time.time(),
        SENDER: account_name,
        DESTINATION: receiver_name,
        MESSAGE_TEXT: message_str
    }

    client_logger.debug(f'Сформировано сообщение: {message_dict}')

    try:
        send_message(sock, message_dict)
        client_logger.info(
            f'Отправлено сообщение для пользователя {receiver_name}')
    except Exception:
        client_logger.critical('Потеряно соединение с сервером.')
        sys.exit(1)
예제 #3
0
def route_client_msg(message, names, clients):
    """
    Адресная отправка сообщений.
    :param message: словарь сообщения
    :param names: список зарегистрированных клиентов
    :param clients: список слушающих клиентских сокетов
    :return:
    """
    if message[DESTINATION] in names and names[message[DESTINATION]] in clients:
        send_message(names[message[DESTINATION]], message)
        server_logger.info(f'Отправлено сообщение пользователю {message[DESTINATION]} '
                           f'от пользователя {message[SENDER]}.')
    elif message[DESTINATION] in names and names[message[DESTINATION]] not in clients:
        raise ConnectionError
    else:
        server_logger.error(
            f'Пользователь {message[DESTINATION]} не зарегистрирован на сервере, '
            f'отправка сообщения невозможна.')
예제 #4
0
def parse_client_msg(message, messages_list, sock, clients_list, names):
    """
    Обработчик сообщений клиентов
    :param message: словарь сообщения
    :param messages_list: список сообщений
    :param sock: клиентский сокет
    :param clients_list: список клиентских сокетов
    :param names: список зарегистрированных клиентов
    :return: словарь ответа
    """
    server_logger.debug(f'Разбор сообщения от клиента: {message}')
    print(f'Разбор сообщения от клиента: {message}')

    # возвращает сообщение о присутствии
    if ACTION in message and message[ACTION] == PRESENCE and \
            TIME in message and USER in message:

        # авторизация
        if message[USER][ACCOUNT_NAME] not in names.keys():
            names[message[USER][ACCOUNT_NAME]] = sock
            send_message(sock, RESPONSE_200)
        else:
            response = RESPONSE_400
            response[ERROR] = 'Имя пользователя уже занято.'
            send_message(sock, response)
            clients_list.remove(sock)
            sock.close()
        return

    # формирует очередь сообщений
    elif ACTION in message and message[ACTION] == MESSAGE and \
            SENDER in message and DESTINATION in message and \
            MESSAGE_TEXT in message and TIME in message:
        messages_list.append(message)
        return

    # выход клиента
    elif ACTION in message and message[ACTION] == EXIT and \
            ACCOUNT_NAME in message:
        clients_list.remove(names[message[USER][ACCOUNT_NAME]])
        names[message[USER][ACCOUNT_NAME]].close()
        del names[message[USER][ACCOUNT_NAME]]
        return

    # возвращает сообщение об ошибке
    else:
        response = RESPONSE_400
        response[ERROR] = 'Некорректный запрос.'
        send_message(sock, response)
        return
예제 #5
0
        f'адрес сервера: {server_addr}, порт: {server_port}, имя пользователя: {client_name}'
    )

    # Начало работы, приветственное сообщение
    try:
        # Создается TCP-сокет клиента
        client_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Соединяется с сервером
        client_tcp.connect((server_addr, server_port))

        # Формирует сообщение о присутствии
        presence_msg = create_presence_msg(client_name)

        # Отправляет сообщение о присутствии серверу
        send_message(client_tcp, presence_msg)

        # Получает и разбирает сообщение от сервера
        server_answer = parse_server_msg(client_tcp, client_name)

        client_logger.info(
            f'Установлено соединение с сервером. Ответ сервера: {server_answer}'
        )
        print(
            f'Установлено соединение с сервером. Ответ сервера: {server_answer}'
        )

    except json.JSONDecodeError:
        client_logger.error('Не удалось декодировать полученную json-строку')
        print('Не удалось декодировать полученную json-строку')
        sys.exit(1)