def setMeAsMaster(sock): print >> sys.stderr, 'Im now master!' ServerData.isMaster = True ServerData.masterId = int(ServerData.myId) ServerData.servers.pop(str(ServerData.myId)) sock.sendto(createJsonStr(203, int(ServerData.myId), 'broadcast', 0, ''), ('255.255.255.255', ServerData.STANDARD_PORT)) for key, value in ServerData.clients.items(): parts = value.split(':') sock.sendto(createJsonStr(203, int(ServerData.myId), key, 0, ''), (parts[0], int(parts[1])))
def handleServerMessage(message, action): last_address_with_std_port = (address[0], ServerData.STANDARD_PORT) # Connect Server if action == 204: if ServerData.isMaster: ServerData.lastId += 1 ServerData.servers[ServerData.lastId] = address[0] + ':' + str(ServerData.STANDARD_PORT) sock.sendto(createJsonStr(205, int(ServerData.myId), ServerData.lastId, message['id'], ''), last_address_with_std_port) # OK Server if action == 205: ServerData.myId = int(message['destiny']) ServerData.masterId = message['origin'] print >>sys.stderr, 'My Id: ', ServerData.myId try: thread.start_new_thread(heartBeat, (sock, last_address_with_std_port)) except Exception as e: print "Error: unable to start thread for heartbeat" print(e) # Heart Beat if action == 202: if ServerData.isMaster: payload = { "clients": ServerData.clients, "servers": ServerData.servers } sock.sendto(createJsonStr(201, int(ServerData.myId), message['origin'], message['id'], json.dumps(payload)), last_address_with_std_port) # Private Server Message if action == 201: if not ServerData.isMaster: ServerData.heartBeatAnswered = True payload = parseJsonStrToObj(message['payload']) ServerData.servers = payload['servers'] ServerData.clients = payload['clients'] ServerData.lastId = int(max(ServerData.servers, key=int)) # Election Victory if action == 203 and int(message['origin']) != int(ServerData.myId): if not ServerData.isMaster: ServerData.masterId = message['origin'] try: thread.start_new_thread(heartBeat, (sock, last_address_with_std_port)) except Exception as e: print "Error: unable to start thread for heartbeat" print(e) # Server Election if action == 206 and not ServerData.isMaster: if int(ServerData.myId) < int(message['origin']): sock.sendto(createJsonStr(207, int(ServerData.myId), message['origin'], message['id'], ''), last_address_with_std_port) # Desist From Election if action == 207 and not ServerData.isMaster: ServerData.shouldIBeMaster = False print >>sys.stderr, 'I can\'t be master.'
def attempMaster(sock, address): for x in range(0, 3): sock.sendto(createJsonStr(204, -1, -1, 0, ''), address) time.sleep(2) if int(ServerData.myId) != -1: break if int(ServerData.myId) == -1: ServerData.myId = 0 ServerData.isMaster = True ServerData.masterId = 0 print >> sys.stderr, 'Im now master!'
def initElectionProcess(sock): myId = int(ServerData.myId) idsToSend = {k: v for k, v in ServerData.servers.items() if int(k) < myId} if not idsToSend: setMeAsMaster(sock) else: print >> sys.stderr, 'Start vote process!' for key, value in idsToSend.items(): parts = value.split(':') sock.sendto(createJsonStr(206, myId, key, 0, ''), (parts[0], int(parts[1]))) try: thread.start_new_thread(shouldIBeMaster, (sock, )) except Exception as e: print "Error: unable to start thread for shouldIBeMaster" print(e)
def heartBeat(sock, serverAddress): while True: sock.sendto( createJsonStr(202, int(ServerData.myId), ServerData.masterId, 0, ''), serverAddress) time.sleep(1) if not ServerData.heartBeatAnswered: ServerData.attempMaster += 1 else: ServerData.heartBeatAnswered = False ServerData.attempMaster = 0 if ServerData.attempMaster >= 2: try: thread.start_new_thread(initElectionProcess, (sock, )) except Exception as e: print "Error: unable to start thread for initElectionProcess" print(e) return if int(ServerData.myId) == int(ServerData.masterId): return
def handleClientMessage(address, message, action): # Register client if action == 104: origin = message['origin'] if origin in ServerData.clients: sock.sendto(createJsonStr(106, 'Invalid', message['destiny'], message['id'], 'Invalid User Name'), address) else: ServerData.clients[origin] = address[0] + ':' + str(address[1]) # Send ACK sock.sendto(createJsonStr(105, message['origin'], message['destiny'], message['id'], message['payload']), address) else: # Send ACK sock.sendto(createJsonStr(105, message['origin'], message['destiny'], message['id'], message['payload']), address) # Private message if action == 101: to = message['destiny'] for key, gen in ServerData.clients.items(): if key == to: parts = ServerData.clients[to].split(':') sock.sendto(data, (parts[0], int(parts[1]))) # Public message elif action == 100: origin = message['origin'] for key, gen in ServerData.clients.items(): if key != origin: parts = ServerData.clients[key].split(':') sock.sendto(data, (parts[0], int(parts[1]))) # Disconnect message elif action == 103: sock.sendto(data, address) ServerData.clients.pop(message['origin']) # List users message elif action == 102: users = '' for key, gen in ServerData.clients.items(): users += key + ', ' sock.sendto(createJsonStr(102, 'SERVER', message['destiny'], message['id'], users[:-2]), address) elif action == 107: weather = getWeather() gdlWeather = 'Check your internet connection and try again.' if weather is not None: gdlWeather = 'The wind for GDL is going to have a speed of: ' + weather['query']['results']['channel']['wind']['speed'] sock.sendto(createJsonStr(107, 'SERVER', message['destiny'], message['id'], gdlWeather), address) elif action == 108: response = postTwitter(message['origin'] + ': ' + message['payload']) sock.sendto(createJsonStr(108, 'SERVER', message['destiny'], message['id'], response), address)
def send(action, source, to, idMessage, content, sock): message = createJsonStr(action, source, to, idMessage, content) sent = sock.sendto(message, (ClientData.serverIP, ClientData.SERVER_PORT))