def send_msg(sender_id, receiver_id, text): if receiver_id in system_users: if receiver_id in my_clients: msg = rolypoly_pb2.GenericMessage() msg.type = 'Message' msg.message.sender_id = sender_id msg.message.receiver_id = receiver_id msg.message.text = text si = my_clients[receiver_id].socketinfo proc_sock.sendto(msg.SerializeToString(), (si.addr, si.port)) elif system_users[receiver_id].sid not in rout_table: find_route(system_users[receiver_id].sid) threading.Timer(MSG_RESEND_TIME, put_event, args=[ Event('SEND_MESSAGE', content=(sender_id, receiver_id, text)) ]).start() else: msg = rolypoly_pb2.GenericMessage() msg.type = 'Message' msg.message.sender_id = sender_id msg.message.receiver_id = receiver_id msg.message.text = text si = rout_table[system_users[receiver_id].sid][1] proc_sock.sendto(msg.SerializeToString(), (si.addr, si.port))
def got_message(s, _): data, _ = s.recvfrom(UDP_MAXLEN) msg = rolypoly_pb2.GenericMessage() msg.ParseFromString(data) if msg.type == 'Connected': print_str('# Connected succesfully #') elif msg.type == 'Ping': msg = rolypoly_pb2.GenericMessage() msg.type = 'Pong' msg.u_id = my_id sock.sendto(msg.SerializeToString(), (s_addr, s_port)) elif msg.type == 'Message': n = users_list[msg.message.sender_id] if msg.message.sender_id in users_list else str(msg.message.sender_id) print_str(n + '> ' + msg.message.text) elif msg.type == 'UserList': set_user_list(msg.userlist.users)
def send_msg(text): msg = rolypoly_pb2.GenericMessage() msg.type = 'Message' msg.message.sender_id = my_id msg.message.receiver_id = receiver_id msg.message.text = text sock.sendto(msg.SerializeToString(), (s_addr, s_port))
def find_route(sid): msg = rolypoly_pb2.GenericMessage() msg.type = 'CountHops' msg.hops.s_id = sid msg.hops.port = my_port for nb in nbs: proc_sock.sendto(msg.SerializeToString(), (nb.addr, nb.port))
def user_discovery(): for nb in nbs: msg = rolypoly_pb2.GenericMessage() msg.type = 'GetKnownUsers' msg.port = my_port proc_sock.sendto(msg.SerializeToString(), (nb.addr, nb.port)) threading.Timer(USERS_DISCOVERY_TIME, put_event, args=[Event('USER_DISCOVERY')]).start()
def send_known_servers(receiver): known_servers[my_id] = millitime() # Update my alive timestamp msg = rolypoly_pb2.GenericMessage() msg.type = 'KnownServers' for i, sid in enumerate(known_servers): msg.known_servers.servers.add() msg.known_servers.servers[i].s_id = sid msg.known_servers.servers[i].last_alive = known_servers[sid] proc_sock.sendto(msg.SerializeToString(), (receiver.addr, receiver.port))
def del_system_user(uid): if uid in system_users: print('# User', system_users[uid].name, '<id: ' + str(uid) + '> disconnected #') del system_users[uid] msg = rolypoly_pb2.GenericMessage() msg.type = 'DelSystemUserInfo' msg.u_id = uid for nb in nbs: proc_sock.sendto(msg.SerializeToString(), (nb.addr, nb.port))
def client_discovery(): for cid in my_clients: msg = rolypoly_pb2.GenericMessage() msg.type = 'Ping' proc_sock.sendto( msg.SerializeToString(), (my_clients[cid].socketinfo.addr, my_clients[cid].socketinfo.port)) threading.Timer(CLIENT_DISCOVERY_TIME, put_event, args=[Event('CLIENT_DISCOVERY')]).start()
def send_user_list(socketinfo): msg = rolypoly_pb2.GenericMessage() msg.type = 'UserList' for i, uid in enumerate(system_users): u = system_users[uid] msg.userlist.users.add() msg.userlist.users[i].s_id = uid msg.userlist.users[i].username = u.name proc_sock.sendto(msg.SerializeToString(), (socketinfo.addr, socketinfo.port))
def update_hops(socketinfo, sid, hops): if sid not in rout_table or rout_table[sid] is None or rout_table[sid][ 0] > hops + 1: rout_table[sid] = (hops + 1, socketinfo) for nb in nbs: msg = rolypoly_pb2.GenericMessage() msg.type = 'HopsFrom' msg.hops.s_id = sid msg.hops.hops = rout_table[sid][0] msg.hops.port = my_port proc_sock.sendto(msg.SerializeToString(), (nb.addr, nb.port))
def add_new_client(clientinfo): uid = clientinfo.uid name = clientinfo.name my_clients[clientinfo.uid] = clientinfo system_users[clientinfo.uid] = SystemUserInfo(uid, name, my_id, clientinfo.last_alive) msg = rolypoly_pb2.GenericMessage() msg.type = 'Connected' proc_sock.sendto(msg.SerializeToString(), (clientinfo.socketinfo.addr, clientinfo.socketinfo.port)) msg = rolypoly_pb2.GenericMessage() msg.type = 'NewSystemUserInfo' msg.new_system_user_info.u_id = uid msg.new_system_user_info.username = name msg.new_system_user_info.s_id = my_id for nb in nbs: proc_sock.sendto(msg.SerializeToString(), (nb.addr, nb.port)) print('# Client', name, '<id: ' + str(clientinfo.uid) + '> connected #')
def new_system_user(info): if info.uid not in system_users: system_users[info.uid] = info msg = rolypoly_pb2.GenericMessage() msg.type = 'NewSystemUserInfo' msg.new_system_user_info.u_id = info.uid msg.new_system_user_info.username = info.name msg.new_system_user_info.s_id = info.sid for nb in nbs: proc_sock.sendto(msg.SerializeToString(), (nb.addr, nb.port)) print('# User', system_users[info.uid].name, '<id: ' + str(info.uid) + '>', 'connected #')
def connect(addr, port): disconnect() msg = rolypoly_pb2.GenericMessage() msg.type = 'ConnectRequest' msg.connect_request.u_id = my_id msg.connect_request.username = my_name global sock, s_addr, s_port sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) window.createfilehandler(sock, tkinter.READABLE, got_message) sock.sendto(msg.SerializeToString(), (addr, port)) s_addr = addr s_port = port
def return_hops(socketinfo, sid): if sid in rout_table: # I looked for route to this sid already if rout_table[sid] is not None: # I know working route msg = rolypoly_pb2.GenericMessage() msg.type = 'HopsFrom' msg.hops.s_id = sid msg.hops.hops = rout_table[sid][0] msg.hops.port = my_port proc_sock.sendto(msg.SerializeToString(), (socketinfo.addr, socketinfo.port)) else: rout_table[ sid] = None # Marking as None means "I don't know the route yet, but started looking for it" find_route(sid)
def send_known_users(receiver): curtime = millitime() for c in my_clients: # Update my clients timestamps system_users[c].last_alive = curtime msg = rolypoly_pb2.GenericMessage() msg.type = 'KnownUsers' for i, uid in enumerate(system_users): suinfo = system_users[uid] msg.known_users.users.add() msg.known_users.users[i].u_id = suinfo.uid msg.known_users.users[i].username = suinfo.name msg.known_users.users[i].s_id = suinfo.sid msg.known_users.users[i].last_alive = suinfo.last_alive proc_sock.sendto(msg.SerializeToString(), (receiver.addr, receiver.port))
def remove_inactive_clients(): curtime = millitime() for cid in list(my_clients): if (curtime - my_clients[cid].last_alive) > CLIENT_MAX_ALIVE_TIME * 1000: print('# Client', system_users[cid].name, '<id: ' + str(cid) + '>', 'disconnected #') del my_clients[cid] del system_users[cid] msg = rolypoly_pb2.GenericMessage() msg.type = 'DelSystemUserInfo' msg.u_id = cid for nb in nbs: proc_sock.sendto(msg.SerializeToString(), (nb.addr, nb.port)) threading.Timer(CLIENT_DISCOVERY_TIME, put_event, args=[Event('REMOVE_INACTIVE_CLIENTS')]).start()
def main(): parser = argparse.ArgumentParser() parser.add_argument('port', type=int) parser.add_argument('config') args = parser.parse_args() load_config(args.config) print('# PyPoly server started #') print('# ID:', my_id, '#') global my_port my_port = args.port threads = [] pt = threading.Thread(target=process) pt.start() threads.append(pt) lt = threading.Thread(target=listener, args=[args.port]) lt.start() threads.append(lt) signal.signal(signal.SIGINT, sigint_handler) signal.pause() # Wait for SIGINT print('\nSIGINT detected, shutting down') q.put(None) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP socket msg = rolypoly_pb2.GenericMessage() msg.type = 'EOF' s.sendto(msg.SerializeToString(), ('127.0.0.1', my_port)) s.close() for t in threads: t.join() return 0
def users_list_request(): msg = rolypoly_pb2.GenericMessage() msg.type = 'GetUserList' sock.sendto(msg.SerializeToString(), (s_addr, s_port))
def listener(port): # Listener is waiting for messages from other servers # As soon as it gets something, it puts it into queue print('Listener started on port', port, '...') s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('', port)) while True: data, client_addr = s.recvfrom(UDP_MAXLEN) msg = rolypoly_pb2.GenericMessage() msg.ParseFromString(data) if msg.type == 'EOF': break elif msg.type == 'GetKnownServers': q.put( Event('SEND_KNOWN_SERVERS', content=SocketInfo(client_addr[0], msg.port))) elif msg.type == 'GetKnownUsers': q.put( Event('SEND_KNOWN_USERS', content=SocketInfo(client_addr[0], msg.port))) elif msg.type == 'KnownServers': q.put( Event('MERGE_KNOWN_SERVERS', content=parse_known_servers(msg.known_servers.servers))) elif msg.type == 'KnownUsers': q.put( Event('MERGE_KNOWN_USERS', content=parse_known_users(msg.known_users.users))) elif msg.type == 'ConnectRequest': q.put( Event('ADD_NEW_CLIENT', content=parse_connect_request(*client_addr, msg.connect_request))) elif msg.type == 'Pong': q.put(Event('CLIENT_ALIVE', content=msg.u_id)) elif msg.type == 'NewSystemUserInfo': q.put( Event('NEW_SYSTEM_USER', content=parse_new_system_user_info( msg.new_system_user_info))) elif msg.type == 'DelSystemUserInfo': q.put(Event('DEL_SYSTEM_USER', content=msg.u_id)) elif msg.type == 'CountHops': q.put( Event('RETURN_HOPS', content=(SocketInfo(client_addr[0], msg.hops.port), msg.hops.s_id))) elif msg.type == 'HopsFrom': q.put( Event('UPDATE_HOPS', content=(SocketInfo(client_addr[0], msg.hops.port), msg.hops.s_id, msg.hops.hops))) elif msg.type == 'Message': q.put( Event('SEND_MESSAGE', content=(msg.message.sender_id, msg.message.receiver_id, msg.message.text))) elif msg.type == 'GetUserList': q.put(Event('SEND_USER_LIST', content=SocketInfo(*client_addr))) s.close() print('Listener stopped')