def run(self): HOST = NCIP #Should connect to NodeController PORT = 9091 #port for pull_server #if NCIP not == '': while True: #loop that keeps connecting to node controller try: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST,PORT)) #print 'Receive process connected...' request = HOSTNAME #device unique ID s.send(request) time.sleep(1) #waits for pull request to go through #TODO might be unneccessary #print 'Request sent: ', request msg = s.recv(4028) #arbitrary. Can put in a config file if msg != 'False': try: #sends incoming messages to msg_handler class msg_handler(msg) s.close() #closes each time a message is received. #print 'Connection closed...' except: print 'Unpack unsuccessful.' else: s.close() #closes each time a message is received. time.sleep(1) except Exception as e: print e print 'Unable to connect to ', NCIP s.close() time.sleep(5) except Exception as e: print e print 'Connection disrupted...' print 'Socket shutting down.' s.close() break s.close()
def run(self): HOST = NCIP #Should connect to NodeController PORT = 9091 #port for pull_server #if NCIP not == '': while True: #loop that keeps connecting to node controller try: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST,PORT)) #print 'Receive process connected...' request = HOSTNAME #device unique ID s.send(request) time.sleep(1) #waits for pull request to go through #TODO might be unneccessary #print 'Request sent: ', request msg = s.recv(4028) #arbitrary. Can put in a config file if msg != 'False': logger.debug("incoming message: %s" % (msg)) try: #sends incoming messages to msg_handler class msg_handler(msg) s.close() #closes each time a message is received. #print 'Connection closed...' except Exception as e: logger.error('Unpack unsuccessful: %s' % (str(e))) else: s.close() #closes each time a message is received. time.sleep(1) except Exception as e: logger.error('Unable to connect to %s: %s' % (NCIP, str(e))) s.close() time.sleep(5) except Exception as e: logger.error('Connection disrupted...Socket shutting down. error: %s' % (str(e)) ) if s: s.close() break if s: s.close()
def run(self): logger.info("Starting DataCache...") # Each buffer is a matrix of queues for organization and indexing purposes. # make incoming buffer self.incoming_bffr = self.make_bffr(len(PRIORITY_ORDER)) # make outgoing buffer self.outgoing_bffr = self.make_bffr(len(PRIORITY_ORDER)) # the main server loop while True: # indicates that the server is flushing the buffers. Shuts down the server until the all queues have been written to a file while self.flush == 1: logger.debug("Cache is in flush state") time.sleep(1) if os.path.exists(self.socket_file): # checking for the file os.remove(self.socket_file) logger.debug("Opening server socket...") # creates a UNIX, STREAMing socket server_sock = socket.socket( socket.AF_UNIX, socket.SOCK_STREAM ) # TODO should this not be a class variable ? server_sock.bind(self.socket_file) # binds to this file path # become a server socket and start listening for clients server_sock.listen(6) while True: if self.flush == 1: # shuts down the server until the all queues have been written to a file logger.debug("Server flush!") server_sock.close() os.remove(self.socket_file) logger.debug("Server flush closed socket") break # accept connections from outside try: client_sock, address = server_sock.accept() except KeyboardInterrupt: logger.info("Shutdown requested...exiting") self.stop() sys.exit(0) except Exception as e: logger.info("server_sock.accept: " + str(e)) self.stop() sys.exit(1) try: data = client_sock.recv(2048) # arbitrary if logger.isEnabledFor(logging.DEBUG): if data != "|o".encode("iso-8859-1"): logger.debug("(DataCache) received data.") if not data: break else: #'Flush' means that there is an external flush request or if WagMan is about to shut down the node controller if data == "Flush".encode("iso-8859-1"): # flush all stored messages into files logger.debug("External flush request made.") self.DC_flush() if stop_process: logger.info("DC has been flushed. Process will stop now.") sys.exit(0) # Indicates that it is a pull request ( somebody want data from the DC) elif data[0] == ord( "|" ): # TODO This could be improved if there is a better way to distinguish between push and pull requests and from incoming and outgoing requests logger.debug("Somebody wants data") # data, dest = data.decode('iso-8859-1').split('|', 1) #splits to get either 'o' for outgoing request or the device location for incoming request dest = data[1:] if dest != "o".encode("iso-8859-1"): logger.debug("Somebody wants data, without o") msg = self.incoming_pull(int(dest)) # pulls a message from that device's queue if not msg: logger.debug("no message") msg = "False".encode("iso-8859-1") else: logger.debug("incoming_pull message: %s" % (msg)) try: client_sock.sendall(msg) # sends the message except: # pushes it back into the incoming queue if the client disconnects before the message is sent try: # Will pass if data is a pull request instead of a full message # TODO default msg_p is 5 for messages pushed back into queue. Improvement recommended. incoming_push(int(dest), 5, msg) except: pass else: logger.debug("Somebody wants data, using o") msg = self.outgoing_pull() # pulls the highest priority message if not msg: msg = "False".encode("iso-8859-15") logger.debug("have no message for external_client_pull") else: logger.debug("sending message to external_client_pull, length %d" % (len(msg))) try: client_sock.sendall(msg) # sends the message except Exception as e: logger.error("client_sock.sendall: " + str(e)) # pushes it back into the outgoing queue if the client disconnects before the message is sent try: # Will pass if data is a pull request instead of a full message # TODO default msg_p is 5 for messages pushed back into queue. Improvement recommended. self.outgoing_push(int(dest), 5, msg) except Exception as e: logger.error("outgoing_push: " + str(e)) pass else: # somebody sends data to the DataCache # logger.debug("datacache got: \""+str(data)+"\"") logger.debug("Somebody sends data") try: header = get_header( data ) # uses the packet handler function get_header to unpack the header data from the message flags = header["flags"] # extracts priorities order = flags[2] # lifo or fifo msg_p = flags[1] recipient_int = header["r_uniqid"] # gets the recipient ID sender_int = header["s_uniqid"] logger.debug("sender_int: %s recipient_int: %s" % (sender_int, recipient_int)) sender = nodeid_int2hexstr(sender_int) recipient = nodeid_int2hexstr(recipient_int) logger.debug("sender: %s recipient: %s NODE_ID: %s" % (sender, recipient, NODE_ID)) for i in range(2): # loops in case device dictionary is not up-to-date # message for the cloud if ( recipient_int == 0 ): # 0 is the default ID for the cloud. Indicates an outgoing push. try: dev_loc = DEVICE_DICT[ sender ] # looks up the location of the sender device ("location" refers to priority!) except KeyError as e: logger.error( "Rejecting message. Sender %s is unknown: %s" % (sender, str(e)) ) continue # do not send message from unknown sender try: if order == False: # indicates lifo. lifo has highest message priority msg_p = 5 # pushes the message into the outgoing buffer to the queue corresponding to the device location and message priority self.outgoing_push(int(dev_loc), msg_p, data) # If the device is registered and the push is successful, no need to try again, break the loop break except Exception as e: logger.error("outgoing_push2: " + str(e)) # The device dictionary may not be up to date. Need to update and try again. # If the device is still not found after first try, move on. update_dev_dict() # this function is in NC_configuration.py # indicates an incoming push # message for the nodecontroller elif recipient == NODE_ID or recipient_int == 1: try: # An error will occur if a guestnode registers and then tries to deregister before the device dictionary has been updated # This may be unlikely but is still possible # If that occurs, need to update the device dictionary and try again msg_handler(data, DEVICE_DICT) break # break the loop if this is successful except Exception as e: logger.error(e) update_dev_dict() # message for a guestnode ? else: try: dev_loc = DEVICE_DICT[ recipient ] # looks up the location of the recipient device # If the device is registered and the push is successful, no need to try again, break the loop self.incoming_push(int(dev_loc), msg_p, data) break except Exception as e: # The device dictionary may not be up to date. Need to update and try again. # If the device is still not found after first try, move on. update_dev_dict() except Exception as e: logger.error("Message corrupt. Will not store in data cache.") logger.error(e) except KeyboardInterrupt as k: logger.info("Data Cache server shutting down...") self.stop() continue # server_sock.close() # os.remove(self.socket_file) # break if os.path.exists(self.socket_file): # checking for the file for a smooth shutdown server_sock.close() os.remove(self.socket_file)
#!/usr/bin/python # coding=utf-8 import os, logging from msg_handler import msg_handler api_root = os.environ.get('api_root', False) access_token = os.environ.get('access_token', False) secret = os.environ.get('secret', False) enable_http_post = os.environ.get('enable_http_post', False) param_dict = {} if api_root: param_dict['api_root'] = api_root if access_token: param_dict['access_token'] = access_token if secret: param_dict['secret'] = secret param_dict['enable_http_post'] = enable_http_post bot = msg_handler(**param_dict) bot.logger.setLevel(level=getattr(logging, os.environ.get('log_level', 'ERROR'))) if __name__ == '__main__': print(bot)
def main(): handler = msg_handler(bot=bot) loop = asyncio.get_event_loop() loop.create_task(handler.start_polling()) schedulers.start() loop.run_forever()
def run(self): #lists keeping track of which queues currently have messages stored in them outgoing_available_queues = list() incoming_available_queues = list() #Each buffer is a matrix of queues for organization and indexing purposes. #make incoming buffer Data_Cache.incoming_bffr = make_bffr(len(PRIORITY_ORDER)) #make outgoing buffer Data_Cache.outgoing_bffr = make_bffr(len(PRIORITY_ORDER)) #the main server loop while True: #indicates that the server is flushing the buffers. Shuts down the server until the all queues have been written to a file while Data_Cache.flush ==1: time.sleep(1) if os.path.exists('/tmp/Data_Cache_server'): #checking for the file os.remove('/tmp/Data_Cache_server') print "Opening server socket..." #creates a UNIX, STREAMing socket server_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server_sock.bind('/tmp/Data_Cache_server') #binds to this file path #become a server socket and start listening for clients server_sock.listen(6) while True: if Data_Cache.flush==1: #shuts down the server until the all queues have been written to a file print 'Server flush!' server_sock.close() os.remove('/tmp/Data_Cache_server') print 'Server flush closed socket' break #accept connections from outside client_sock, address = server_sock.accept() try: data = client_sock.recv(2048) #arbitrary #print 'Server received: ', data if not data: break else: #'Flush' means that there is an external flush request or if WagMan is about to shut down the node controller if data == 'Flush': #flush all stored messages into files print 'Flush request made.' DC_flush(incoming_available_queues, outgoing_available_queues) #Indicates that it is a pull request elif data[0] == '|': #TODO This could be improved if there is a better way to distinguish between push and pull requests and from incoming and outgoing requests data, dest = data.split('|', 1) #splits to get either 'o' for outgoing request or the device location for incoming request if dest != 'o': msg = incoming_pull(int(dest), incoming_available_queues) #pulls a message from that device's queue if msg == 'None': msg = 'False' try: client_sock.sendall(msg) #sends the message except: #pushes it back into the incoming queue if the client disconnects before the message is sent try: #Will pass if data is a pull request instead of a full message #TODO default msg_p is 5 for messages pushed back into queue. Improvement recommended. incoming_push(int(dest),5, msg, incoming_available_queues, outgoing_available_queues) except: pass else: msg = outgoing_pull(outgoing_available_queues) #pulls the highest priority message if msg == None: msg = 'False' try: client_sock.sendall(msg) #sends the message except Exception as e: print e #pushes it back into the outgoing queue if the client disconnects before the message is sent try:#Will pass if data is a pull request instead of a full message #TODO default msg_p is 5 for messages pushed back into queue. Improvement recommended. outgoing_push(int(dest),5,msg, outgoing_available_queues, incoming_available_queues) except Exception as e: #print e pass time.sleep(1) else: try: header = get_header(data) #uses the packet handler function get_header to unpack the header data from the message flags = header['flags'] #extracts priorities order = flags[2] #lifo or fifo msg_p = flags[1] recipient = header['r_uniqid'] #gets the recipient ID sender = header['s_uniqid'] for i in range(2): #loops in case device dictionary is not up-to-date if recipient == 0: #0 is the default ID for the cloud. Indicates an outgoing push. try: dev_loc = DEVICE_DICT[str(sender)] #looks up the location of the sender device if order==False: #indicates lifo. lifo has highest message priority msg_p=5 #pushes the message into the outgoing buffer to the queue corresponding to the device location and message priority outgoing_push(int(dev_loc), msg_p, data, outgoing_available_queues, incoming_available_queues) #If the device is registered and the push is successful, no need to try again, break the loop break except Exception as e: #The device dictionary may not be up to date. Need to update and try again. #If the device is still not found after first try, move on. DEVICE_DICT = update_dev_dict() #this function is in NC_configuration.py #indicates an incoming push elif str(recipient) == HOSTNAME: try: #An error will occur if a guestnode registers and then tries to deregister before the device dictionary has been updated #This may be unlikely but is still possible #If that occurs, need to update the device dictionary and try again msg_handler(data,DEVICE_DICT) break #break the loop if this is successful except Exception as e: #print e DEVICE_DICT = update_dev_dict() else: try: dev_loc = DEVICE_DICT[str(recipient)] #looks up the location of the recipient device #If the device is registered and the push is successful, no need to try again, break the loop incoming_push(int(dev_loc),msg_p,data, incoming_available_queues, outgoing_available_queues) break except Exception as e: #The device dictionary may not be up to date. Need to update and try again. #If the device is still not found after first try, move on. DEVICE_DICT = update_dev_dict() except Exception as e: print 'Message corrupt. Will not store in data cache.' print e time.sleep(1) except KeyboardInterrupt, k: print "Data Cache server shutting down..." break