diff --git a/client/__main__.py b/client/__main__.py index 8845a51..109c51a 100644 --- a/client/__main__.py +++ b/client/__main__.py @@ -46,12 +46,12 @@ def read_response(response, mode='w'): if mode == 'w': logger.debug(f"Response Message: {response.get('alert')}") print( - f"Response Message: {response.get('alert')}" + f"{response.get('alert')}" ) else: print( f"{response.get('user')['account_name']}: {response.get('user')['status']}\n", - f"Server: {response.get('alert')}" + f"{response.get('alert')}" ) else: logger.critical(f"Error request: {response.get('error')}") @@ -77,32 +77,99 @@ def read_response(response, mode='w'): hash_obj = hashlib.sha1() hash_obj.update(b'secret_key') + user = { + "account_name": username, + "status": 'Online' + } + msg_presence = json.dumps( { "action": "presence", "time": datetime.now().timestamp(), "type": "status", - "user": { - "account_name": username, - "status": input("Your message: ") - } + "user": user } ) - # отправить сообщение серверу; sock.send(msg_presence.encode()) - """ - msg_action = json.dumps( - { - "action": input("Enter action (lower_text): "), - "data": input("Enter data: ") - } - ) - - sock.send(msg_action.encode()) - """ - # получить ответ сервера; data = sock.recv(1024) - read_response(data) + + while True: + action = input("Enter action (chat, p2p, text, exit): ") + if action == 'exit': + logger.info(f"client closed") + sock.close() + break + elif action == 'text': + msg_action = json.dumps( + { + "action": input("Enter action (lower_text, upper_text): "), + "data": input("Enter data: "), + "user": user + } + ) + sock.send(msg_action.encode()) + # получить ответ сервера; + data = sock.recv(1024) + read_response(data) + elif action == 'chat': + join_request = json.dumps( + { + "action": "join", + "time": datetime.now().timestamp(), + "room": "#common", + "user": user + } + ) + sock.send(join_request.encode()) + data = sock.recv(1024) + while True: + message = input("Enter message (or exit): ") + if message == 'exit': + leave_request = json.dumps( + { + "action": "leave", + "time": datetime.now().timestamp(), + "room": "#common", + "user": user + } + ) + sock.send(leave_request.encode()) + break + chat_request = json.dumps({ + "action": "msg", + "time": datetime.now().timestamp(), + "to": '#common', + "from": username, + "encoding": "utf-8", + "message": message, + "user": user + }) + # отправить сообщение серверу; + sock.send(chat_request.encode()) + # получить ответ сервера; + data = sock.recv(1024) + read_response(data) + elif action == 'p2p': + sendto = input("Enter user_name for send: ") + while True: + message = input("Enter message (or exit): ") + if message == 'exit': + break + + p2p_request = json.dumps({ + "action": "msg", + "time": datetime.now().timestamp(), + "to": sendto, + "from": username, + "encoding": "utf-8", + "message": message, + "user": user + }) + # отправить сообщение серверу; + sock.send(p2p_request.encode()) + # получить ответ сервера; + data = sock.recv(1024) + read_response(data) else: while True: # Постоянный опрос сервера data = sock.recv(1024) diff --git a/server/__main__.py b/server/__main__.py index 705023f..69a2547 100644 --- a/server/__main__.py +++ b/server/__main__.py @@ -6,7 +6,8 @@ from socket import socket, AF_INET, SOCK_STREAM import argparse import select - +import threading +import collections from protocol import ( @@ -27,42 +28,41 @@ def get_client_fullname(host, port): return f'{ host }:{ port }' -def read_requests(r_clients, all_clients): +def read_requests(sock, allclients): """ Чтение запросов из списка клиентов """ - responses = [] + #responses = [] #print('read_requests') - for sock in r_clients: - try: - print('client 1') - data = sock.recv(1024).decode('utf-8') - #responses[sock] = json.loads(data) - responses.append(json.loads(data)) - print(responses[sock]) - except: - print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) - #all_clients.remove(sock) - - return responses - - -def write_responses(requests, w_clients, all_clients): - for req in requests: +#for sock in r_clients: + try: + data = sock.recv(1024).decode('utf-8') + #responses[sock] = json.loads(data) + #print(responses[sock]) + requests.append(json.loads(data)) + #print(requests[sock]) + except: + print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) + clients.remove(sock) + + #return responses + + +def write_responses(req, sock, all_clients): +#for req in requests: #print('write_responses') #print(req) # Разобрать все запросы response = handle_client_request(req) response_string = json.dumps(response) - for sock in w_clients: - try: - # отправить всем - sock.send(response_string.encode('utf-8')) - #print('Сообщение отправлено') - except: # Сокет недоступен, клиент отключился - print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) - #sock.close() - #all_clients.remove(sock) - requests.remove(req) + #for sock in w_clients: + try: + # отправить всем + sock.send(response_string.encode('utf-8')) + #print('Сообщение отправлено') + except: # Сокет недоступен, клиент отключился + print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) + #sock.close() + #all_clients.remove(sock) parser = createParser() @@ -74,11 +74,11 @@ def write_responses(requests, w_clients, all_clients): sock.listen(5) sock.settimeout(0.2) -requests = [] +requests = collections.deque() +responses = collections.deque() connections = [] clients = [] - try: while True: try: @@ -98,10 +98,23 @@ def write_responses(requests, w_clients, all_clients): try: r, w, e = select.select(clients, clients, [], wait) - #print('r:', len(r), ' w:', len(w), ' e:', len(e)) - requests = read_requests(r, clients) # Сохраним запросы клиентов + + for sock in r: + #print('r:', len(r), ' w:', len(w), ' e:', len(e)) + read_thred = threading.Thread( + target=read_requests, args=(sock, clients), + ) + read_thred.start() + + # requests = read_requests(r, clients) # Сохраним запросы клиентов if requests: - write_responses(requests, w, clients) # Выполним отправку ответов + request = requests.popleft() + for sock in w: + write_thred = threading.Thread( + target=write_responses, args=(request, sock, clients) + ) + write_thred.start() + #write_responses(requests, w, clients) # Выполним отправку ответов except: pass # Ничего не делать, если какой-то клиент отключился diff --git a/server/join/controllers.py b/server/join/controllers.py new file mode 100644 index 0000000..7db3a53 --- /dev/null +++ b/server/join/controllers.py @@ -0,0 +1,17 @@ +from protocol import make_response, make_400 +from log import log + +@log +def jim_join(request): + room = request.get('room') + user = request.get('user') + print('jim_join') + if not user or not room: + return make_400(request) + return make_response( + request, + 200, + send_to=room, + send_from=user['account_name'], + alert=f"{user['account_name']} join the room: {room} " + ) diff --git a/server/join/routes.py b/server/join/routes.py new file mode 100644 index 0000000..12eb958 --- /dev/null +++ b/server/join/routes.py @@ -0,0 +1,6 @@ +from .controllers import jim_join + + +routes = [ + {'action': 'join', 'controller': jim_join} +] diff --git a/server/leave/controllers.py b/server/leave/controllers.py new file mode 100644 index 0000000..f5e9485 --- /dev/null +++ b/server/leave/controllers.py @@ -0,0 +1,16 @@ +from protocol import make_response, make_400 +from log import log + +@log +def jim_leave(request): + room = request.get('room') + user = request.get('user') + if not user or not room: + return make_400(request) + return make_response( + request, + 200, + send_to=room, + send_from=user['account_name'], + alert=f"{user['account_name']} leave the room: {room} " + ) diff --git a/server/leave/routes.py b/server/leave/routes.py new file mode 100644 index 0000000..7d7ffad --- /dev/null +++ b/server/leave/routes.py @@ -0,0 +1,6 @@ +from .controllers import jim_leave + + +routes = [ + {'action': 'leave', 'controller': jim_leave} +] diff --git a/server/msg/controllers.py b/server/msg/controllers.py new file mode 100644 index 0000000..068afa2 --- /dev/null +++ b/server/msg/controllers.py @@ -0,0 +1,22 @@ +from protocol import make_response, make_400 +from log import log + +@log +def jim_msg(request): + request_to = request.get('to') + request_from = request.get('from') + user = request.get('user') + print('jim_msg') + + message = request.get('message') + + if not user or not request_to or not request_from: + return make_400(request) + return make_response( + request, + 200, + send_to=request_to, + send_from=request_from, + alert=f"{user['account_name']}: {message} " + ) + diff --git a/server/msg/routes.py b/server/msg/routes.py new file mode 100644 index 0000000..9d69509 --- /dev/null +++ b/server/msg/routes.py @@ -0,0 +1,6 @@ +from .controllers import jim_msg + + +routes = [ + {'action': 'msg', 'controller': jim_msg} +] diff --git a/server/presence/controllers.py b/server/presence/controllers.py index c24cadf..d42bfad 100644 --- a/server/presence/controllers.py +++ b/server/presence/controllers.py @@ -2,12 +2,15 @@ from log import log @log -def send_presence(request): +def jim_presence(request): + user = request.get('user') if not user: return make_400(request) return make_response( request, 200, - alert=f"{user['account_name']} Your message is send " + send_to=user['account_name'], + send_from=user['account_name'], + alert=f"HI {user['account_name']}" ) diff --git a/server/presence/routes.py b/server/presence/routes.py index 6679a46..bb1a00d 100644 --- a/server/presence/routes.py +++ b/server/presence/routes.py @@ -1,6 +1,6 @@ -from .controllers import send_presence +from .controllers import jim_presence routes = [ - {'action': 'presence', 'controller': send_presence} + {'action': 'presence', 'controller': jim_presence} ] diff --git a/server/protocol.py b/server/protocol.py index 6886d51..6dd2c17 100644 --- a/server/protocol.py +++ b/server/protocol.py @@ -10,10 +10,11 @@ def validate_request(raw): return False -def make_response(request, code, data=None, error=None, alert=None): +def make_response(request, code, send_to=None, send_from=None, data=None, error=None, alert=None): return { 'action': request.get('action'), - 'user': request.get('user'), + 'to': send_to, + 'from': send_from, 'time': datetime.now().timestamp(), 'data': data, 'response': code, diff --git a/server/quit/controllers.py b/server/quit/controllers.py new file mode 100644 index 0000000..825a6c9 --- /dev/null +++ b/server/quit/controllers.py @@ -0,0 +1,16 @@ +from protocol import make_response, make_400 +from log import log + +@log +def jim_quit(request): + user = request.get('user') + + if not user: + return make_400(request) + return make_response( + request, + 200, + send_to=user['account_name'], + send_from=user['account_name'], + alert=f"{user['account_name']} quit " + ) diff --git a/server/quit/routes.py b/server/quit/routes.py new file mode 100644 index 0000000..7890e3a --- /dev/null +++ b/server/quit/routes.py @@ -0,0 +1,6 @@ +from .controllers import jim_quit + + +routes = [ + {'action': 'quit', 'controller': jim_quit} +] diff --git a/server/settings.py b/server/settings.py index 8968d2d..4b42020 100644 --- a/server/settings.py +++ b/server/settings.py @@ -5,5 +5,5 @@ ) INSTALLED_MODULES = [ - 'text', 'presence', 'exception' + 'text', 'presence', 'exception', 'leave', 'msg', 'join', 'quit' ] \ No newline at end of file diff --git a/server/text/controllers.py b/server/text/controllers.py index 0baff3d..392ce23 100644 --- a/server/text/controllers.py +++ b/server/text/controllers.py @@ -10,12 +10,16 @@ @login_required def get_upper_text(request): data = request.get('data') - if not data: + user = request.get('user') + print('upper') + if not data or not user: return make_400(request) return make_response( request, 200, - data.upper() + data.upper(), + send_to=user['account_name'], + send_from=user['account_name'], ) @@ -25,10 +29,16 @@ def get_upper_text(request): @LoginRequired() def get_lower_text(request): data = request.get('data') - if not data: + user = request.get('user') + + print('lower') + print(data, user) + if not data or not user: return make_400(request) return make_response( request, 200, - data.lower() + data.lower(), + send_to=user['account_name'], + send_from=user['account_name'], )