def poll(self): self.is_alive = True while True: if not self.is_alive: break # Принимает сообщение от сервера по протоколу # data = self.sock.recv(1024) # print(data) listen_sct = MyMessMessage() response = listen_sct.mess_get(self.sock) if self.fields.RESPONSE in response: if response[self.fields.RESPONSE] == self.codes.OK: print('Грит {} ---- Полный {}'.format( response[self.fields.RESPONSE], response)) elif response[self.fields.RESPONSE] == self.codes.ACCEPTED: print('Запрос успешен {}'.format(response)) else: print('Неверный код ответа от сервера') elif self.fields.ACTION in response: if response[self.fields.ACTION] == self.actions.MSG: print('{} говорит --> {}'.format( response[self.jim_other.USER][self.jim_other.FROM], response[self.fields.MESSAGE])) self.process_message(response) elif response[self.fields.ACTION] == self.actions.RESPONSE: self.sock_in_queue.put(response)
def __init__(self, name, addr='localhost', port=7777): self.name = name self.addr = addr self.port = port # JIM self.jim_other = MyJimOtherValue() self.actions = MyJimActions() self.codes = MyJimResponseCode() # Пресенс по дефолту self.presence = MyMessMessage( action=self.actions.PRESENCE, user={self.jim_other.ACCOUNT_NAME: self.name}) # Подключиться self.socket = self.connect() # Создаём базу для клиента self.db = ClientDbControl('{}.db'.format(self.name), 'a_client/db', Base) # Сразу пишем туда подключившегося юзера self.add_to_client_db() # тут будет очередь self.request_queue = Queue() # Стартует GUI - пока не стартуем, только экземпяр хз для чего, но мб пригодится # self.gui = MyGui() '''
def send_message(self, to_user_name, message_str): msg = MyMessMessage(action=self.actions.MSG, message=message_str, user={ self.jim_other.FROM: self.name, self.jim_other.TO: to_user_name }) # Отправляем на сервер msg.mess_send(self.socket)
def get_contacts(self): """Получить список контактов""" # формируем сообщение list_message = MyMessMessage(action=self.jim_other.GET_CONTACTS, user=self.name) # отправляем list_message.other_send(self.socket) # return {'user': '******', 'time': 'Time to kill!'} data = self.request_queue.get() return data
def add_avatar(self, avatar_name, file): # Отправляем аватар на сервер, пока только имя add_avatar__to_server = MyMessMessage(action=self.actions.AVATAR, user=self.name, avatar={ self.jim_other.AVATAR_NAME: avatar_name, self.jim_other.FILE_ACTION: self.jim_other.ADD }) add_avatar__to_server.other_send(self.socket) # Пишем аватар в клиенте self.db.add_avatar(file) self.db.commit()
def _read_requests(self, r_clients): messages = [] for sock in r_clients: try: # Получаем входящие сообщения через метод сервера и лепим в сообщения get_message = MyMessMessage().mess_get(sock) # УБИРАЕТ ЧЁРТОВО ВРЕМЯ, НЕДЕЛЯ ПОИСКОВ ОШИБКИ РАДИ ЭТОГО КОСТЫЛЯ ( get_message.pop('time') # get_message = sock.recv(1024) print('Получено от клиента {}'.format(get_message)) # Сохраняем сообщение + сокет от которого оно пришло messages.append((get_message, sock)) except: print('Отключился в чтении') print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) # Чистим общий список клиентов от отвалившихся self._clients.remove(sock) # Возвращаем словарь сообщений return messages
def _get_accept_in(self): from_client_name = self.client_name try: # Принимает коннект от клиента client_socket, addr = self.socket.accept() # Ловит пресенс от клиента presence = MyMessMessage() presence = presence.mess_get(client_socket) print(presence) # Будем писать подключившегося юзера в базу connected_user_name = presence[self.jim_other.USER][ self.jim_other.ACCOUNT_NAME] self.db.add_client(connected_user_name) self.db.commit() # Спорная проверка # TODO: перенести всё в класс MyMessMessage, проверять возможные данные приходящие в action if presence[self.fields.ACTION] == self.actions.PRESENCE: # Получаем имя подключившегося юзера from_client_name = presence[self.jim_other.USER][ self.jim_other.ACCOUNT_NAME] # Пока так print("Подключается юзер ---{}--- адрес: {}".format( from_client_name, str(addr))) # TODO: проверить наличие пользователя в базе, если нет, то добавить 'if not' # TODO: запись в историю подключения клиента # Оправляет респонс response = MyMessMessage(response=self.codes.OK) response.response_send(client_socket) # TODO: else: - отправлять сообщение о неверном запросе except OSError as e: pass # timeout вышел else: print("Юзер ---{}--- успешно подключился".format(from_client_name)) # Добавляем в список подключившегося self._clients.append(client_socket) # Добавляем имя клиента в словарь - имя: сокет self.client_names[from_client_name] = client_socket finally: # Поверяем события wait = 0 r = [] w = [] try: r, w, e = select.select(self._clients, self._clients, [], wait) except: pass requests = self._read_requests(r) # Получаем входящие сообщения self._write_responses(requests, w) # Выполним отправку исходящих сообщений
def _write_responses(self, messages, w_clients): for client_said in messages: # from_name = соккет от которого пришло сообщение. Пока ни где не используется message, from_name = client_said to_client = None sock = None user_mode = 'User on line' # Будем проверять, указан ли получатель if self.jim_other.TO in message[self.jim_other.USER]: # Если указанно имя получателя if message[self.jim_other.USER][self.jim_other.TO] is not None: # Находим имя to_client = message[self.jim_other.USER][self.jim_other.TO] else: # Если сообщение не является MSG if self.actions.MSG not in message[self.fields.ACTION]: # Считаем, что отправитель сам же является получателем to_client = message[self.jim_other.USER] # Находим сокет по имени if to_client is not None: try: sock = self.client_names[to_client] user_mode = 'User on line' except KeyError: user_mode = 'User off line' print(message) # Для принта контактов if message[self.fields.ACTION] == self.jim_other.GET_CONTACTS: print('Клиент запросил контакты') client_login = message[self.jim_other.USER] contacts = self.db.get_contacts(client_login) response = MyMessMessage(response=self.codes.ACCEPTED, quantity=len(contacts)) print('Список контактов клиента {}'.format(contacts)) response.response_send(sock) # Перебираем и отправляем контакты contacts_list_send = MyMessMessage( action=self.actions.RESPONSE, message=contacts) contacts_list_send.other_send(sock) # for contact in contacts: # contacts_list_send = MyMessMessage(action=self.actions.RESPONSE, message=contact) # contacts_list_send.other_send(sock) # break elif message[self.fields.ACTION] == self.jim_other.ADD_CONTACT: print('add contact') add = self.db.add_contact(message[self.jim_other.USER], message[self.jim_other.CONTACT_NAME]) if add is not False: self.db.commit() response = MyMessMessage(response=self.codes.ACCEPTED) response.response_send(sock) else: response = MyMessMessage(response=self.codes.WRONG_REQUEST) response.response_send(sock) print('Такой контакт не зарегистрирован') elif message[self.fields.ACTION] == self.jim_other.DEL_CONTACT: print('del contact') del_contact = self.db.del_contact( message[self.jim_other.USER], message[self.jim_other.CONTACT_NAME]) if del_contact is not False: self.db.commit() response = MyMessMessage(response=self.codes.ACCEPTED) response.response_send(sock) else: response = MyMessMessage(response=self.codes.WRONG_REQUEST) response.response_send(sock) print('Не возможно удалить не существующий контакт') elif message[self.fields.ACTION] == self.actions.AVATAR: if message[self.actions.AVATAR][ self.jim_other.FILE_ACTION] == self.jim_other.ADD: add_avatar = self.db.add_avatar( message[self.actions.AVATAR][ self.jim_other.AVATAR_NAME], message[self.jim_other.USER]) if add_avatar is not False: self.db.commit() response = MyMessMessage(response=self.codes.ACCEPTED) response.response_send(sock) elif message[self.fields.ACTION] == self.actions.MSG: # Если есть имя клиента которому отправляем # TODO: проверять в БД существует такой клиент или нет # TODO: а потом проверять есть ли связь между клиентами from и to if sock is not None: self.db.add_message_history( message[self.jim_other.USER][self.jim_other.FROM], message[self.jim_other.USER][self.jim_other.TO], message[self.fields.MESSAGE]) self.db.commit() if user_mode != 'User off line': print(user_mode) if sock is not None: # Формируем сообщение и пуляем на сокет соответствующий имени print('Сокет{}'.format(sock)) transfer = MyMessMessage(**message) transfer.mess_send(sock) else: # Если нет, то отправлять будем всем кто читает! for sock in w_clients: if sock == self.client_names[message[ self.jim_other.USER][self.jim_other.FROM]]: continue transfer = MyMessMessage(**message) transfer.mess_send(sock)
def del_contact(self, del_name): del_contact = MyMessMessage(action=self.jim_other.DEL_CONTACT, user=self.name, contact_name=del_name) del_contact.other_send(self.socket)
def add_contact(self, new_name): add_contact = MyMessMessage(action=self.jim_other.ADD_CONTACT, user=self.name, contact_name=new_name) add_contact.other_send(self.socket)
class MyMessClient: def __init__(self, name, addr='localhost', port=7777): self.name = name self.addr = addr self.port = port # JIM self.jim_other = MyJimOtherValue() self.actions = MyJimActions() self.codes = MyJimResponseCode() # Пресенс по дефолту self.presence = MyMessMessage( action=self.actions.PRESENCE, user={self.jim_other.ACCOUNT_NAME: self.name}) # Подключиться self.socket = self.connect() # Создаём базу для клиента self.db = ClientDbControl('{}.db'.format(self.name), 'a_client/db', Base) # Сразу пишем туда подключившегося юзера self.add_to_client_db() # тут будет очередь self.request_queue = Queue() # Стартует GUI - пока не стартуем, только экземпяр хз для чего, но мб пригодится # self.gui = MyGui() ''' self._gui_start() запустится после получения списка контактов - не запустится ''' def connect(self): # Создать сокет TCP sct = socket(AF_INET, SOCK_STREAM) # Соединиться с сервером sct.connect((self.addr, self.port)) # Отправляет пресенс # self.presence.mess_send(sock) self.presence.mess_send(sct) return sct def disconnect(self): # Отключаемся self.socket.close() # Запишет клиента в базу на клиенте? def add_to_client_db(self): self.db.add_user(self.name) self.db.commit() # Чтобы получать контакты def get_contacts(self): """Получить список контактов""" # формируем сообщение list_message = MyMessMessage(action=self.jim_other.GET_CONTACTS, user=self.name) # отправляем list_message.other_send(self.socket) # return {'user': '******', 'time': 'Time to kill!'} data = self.request_queue.get() return data def add_contact(self, new_name): add_contact = MyMessMessage(action=self.jim_other.ADD_CONTACT, user=self.name, contact_name=new_name) add_contact.other_send(self.socket) def del_contact(self, del_name): del_contact = MyMessMessage(action=self.jim_other.DEL_CONTACT, user=self.name, contact_name=del_name) del_contact.other_send(self.socket) def add_avatar(self, avatar_name, file): # Отправляем аватар на сервер, пока только имя add_avatar__to_server = MyMessMessage(action=self.actions.AVATAR, user=self.name, avatar={ self.jim_other.AVATAR_NAME: avatar_name, self.jim_other.FILE_ACTION: self.jim_other.ADD }) add_avatar__to_server.other_send(self.socket) # Пишем аватар в клиенте self.db.add_avatar(file) self.db.commit() def get_avatar(self): return self.db.get_avatar() def send_message(self, to_user_name, message_str): msg = MyMessMessage(action=self.actions.MSG, message=message_str, user={ self.jim_other.FROM: self.name, self.jim_other.TO: to_user_name }) # Отправляем на сервер msg.mess_send(self.socket)