def create_chat_message(self, message): """ Создает словарь/json сообщения для последующей отправки в чат. :param message: сообщение для заполнения поля message в json :return: словарь/json сообщения """ #print('**' + message + '**') return JIMMsg(action='msg', message=message).msg
def get_client_contacts(self): get_contacts_msg = JIMMsg(action='get_contacts').msg utils.send_message(self.client.s, get_contacts_msg) accept = utils.get_message(self.client.s) contacts = utils.get_message(self.client.s)['message'] # if accept['quantity']: # print('Ваши контакты: ') # for i in range(accept['quantity']): # print(utils.get_message(self.client.s)['user']['account_name']) return contacts
def test_write_responses(self, monkeypatch): monkeypatch.setattr("socket.socket", MySocket) requests = {} sock_r = socket.socket() # сокет для словаря requests requests[sock_r] = JIMMsg('msg', 'Hello!').msg sock_w = socket.socket() # сокет для приема сообщений self.serv.clients.append(sock_w) assert self.serv.write_responses(requests, self.serv.clients) == len(requests[sock_r]) requests[sock_r] = JIMMsg('presence').msg with raises(Exception): self.serv.write_responses(requests, self.serv.clients) requests = {} assert self.serv.write_responses(requests, self.serv.clients) == len('') requests[sock_r] = JIMMsg('msg', 'Hello!').msg self.serv.clients.remove(sock_w) assert self.serv.write_responses(requests, self.serv.clients) == len('')
def write_responses(self, requests, w_clients): """ Отправляет клиентам-читателям запросы клиентов-писателей. Удаляет клиента из списка всех клиентов при отключении. :param requests: словарь с запросами клиентов-писателей :param w_clients: список клиентов-читателей :return: суммарная длина отправленных сообщений (нужно только для тестирования) """ test_len = 0 for sock in requests: if requests[sock]['action'] == 'add_contact': try: self.dwh.add_contact( self.clients[sock], requests[sock]['user']['account_name']) resp = JIMResponse(response_code=200).resp print(requests[sock]['user']['account_name'], 'added as a contact to contact list of', self.clients[sock]) sock.send(json.dumps(resp).encode('utf-8')) except Exception as e: resp = JIMResponse(response_code=500).resp sock.send(json.dumps(resp).encode('utf-8')) elif requests[sock]['action'] == 'del_contact': try: self.dwh.del_contact( self.clients[sock], requests[sock]['user']['account_name']) resp = JIMResponse(response_code=200).resp print(requests[sock]['user']['account_name'], 'deleted from contact list of', self.clients[sock]) sock.send(json.dumps(resp).encode('utf-8')) except Exception as e: resp = JIMResponse(response_code=500).resp sock.send(json.dumps(resp).encode('utf-8')) elif requests[sock]['action'] == 'msg': for w_sock in w_clients: if sock != w_sock: try: resp = JIMMsg( action='msg', message=requests[sock]['message']).msg test_len += len(resp) #print(resp) w_sock.send(json.dumps(resp).encode('utf-8')) except: print('Клиент {} {} отключился'.format( w_sock.fileno(), w_sock.getpeername())) w_sock.close() self.clients.pop(w_sock) else: raise Exception( 'Сообщение должно иметь action "msg" или "add_contact"!') return test_len
def recv(self, n): return dict_to_bytes(JIMMsg('msg', 'Hello!').msg)
def mainloop(self): """ Основная функция: - в цикле: - если новый клиент подключился, добавляет его в список клиентов, принимает presence-сообщение и отвечает 'OK' - делит всех клиентов на писателей и читателей - сохраняет запросы клиентов-писателей с помощью функции read_requests - отправляет сообщения клиентам-читателям с помощью функции write_responses :return: None """ self.create_db_session() # создание сессии для работы с БД while True: try: conn, addr = self.s.accept() # Проверка подключений except OSError as e: pass # timeout вышел else: print("Получен запрос на соединение с %s" % str(addr)) # self.clients.append(conn) self.clients[conn] = '' # Принятие presence-сообщения клиента received_msg = json.loads(conn.recv(1024).decode('utf-8')) # Формирование ответа клиенту if received_msg['action'] == 'presence': username = received_msg['user']['account_name'] self.clients[conn] = username if not self.dwh.client_exists(username): self.dwh.add_client(username) print('Клиент добавлен в базу: ', self.dwh.get_client_by_username(username)) else: print('Клиент уже есть в базе: ', self.dwh.get_client_by_username(username)) self.dwh.add_logon(username, addr[0]) # self.dwh.get_logon_history(username) response = JIMResponse(200).resp # Отправка ответа клиенту conn.send(json.dumps(response).encode('utf-8')) received_msg_get_contacts = json.loads( conn.recv(1024).decode('utf-8')) if received_msg_get_contacts['action'] == 'get_contacts': contacts = self.dwh.get_contacts(username) accept = JIMResponse(response_code=202, quantity=len(contacts)).resp conn.send(json.dumps(accept).encode('utf-8')) time.sleep(0.1) contact_names = [] for i in range(accept['quantity']): contact_names.append(contacts[i].Name) contacts_msg = JIMMsg(action='contact_list', message=contact_names).msg conn.send((json.dumps(contacts_msg).encode('utf-8'))) # contact = JIMMsg(action='contact_list', login=contacts[i].Name).msg # conn.send(json.dumps(contact).encode('utf-8')) else: raise Exception('Первым сообщением должен быть presence!') finally: wait = 0 r = [] w = [] try: r, w, e = select.select(self.clients.keys(), self.clients.keys(), [], wait) #print(r, w) except Exception as e: pass requests = self.read_requests( r) # Сохраним запросы клиентов на отправку сообщений self.write_responses(requests, w) # Выполним отправку сообщений клиентам
def create_presence_message(self): """ Создает словарь/json presence-сообщения. :return: словарь/json presence-сообщения """ return JIMMsg(action='presence', login=self.user.username).msg
def del_contact(self, contact_username): del_contact_msg = JIMMsg(action='del_contact', login=contact_username).msg #print(del_contact_msg) utils.send_message(self.client.s, del_contact_msg)
def add_contact(self, contact_username): add_contact_msg = JIMMsg(action='add_contact', login=contact_username).msg #print(add_contact_msg) utils.send_message(self.client.s, add_contact_msg)