def main(): header = """ ______________________________________________________ | | | Command Pattern - Server | | . . . . . . . __________ | | . . -----> | | | | . . <----- | | | | . . . . . . . |__________| | | | | Author: Marcus Ottosson <*****@*****.**> | |______________________________________________________| Running @ local: {local}:5555""".format(local=command.get_local_ip()) command.cls() print header thread = threading.Thread(target=server) thread.daemon = True thread.start() try: while True: time.sleep(1) except KeyboardInterrupt: pass
def connect(self): """Connect to server This method is responsible for keeping the server unaware of where a client is at, until a client attempts to connect. It works by first establishing a connection to a fixed point; the server. It then emits a message, containing a unique id for this particular client, along with a unique port under which the client will be listening for responses. The server will then only send messages to clients that were originally responsible for making the request. Example: # Client 1 > create age 5 > history 0: (client1_specific_id) # Client 2 > create color 5 > history 0: (client2_specific_id) """ # Connect to stable server port endpoint = "tcp://{ip}:{port}".format( ip=self.requests_ip, port=self.requests_port) log.info("Connecting to %s.." % endpoint) self.requests.connect(endpoint) # Bind random incoming port try: results_port = self.results.bind_to_random_port("tcp://*") except zmq.error.ZMQError: raise command.Connection("Could not connect to " "random port, try again later.") if self.requests_ip == 'localhost': # The server is running locally, this means the # client must be running locally too. results_ip = 'localhost' elif self.requests_ip.startswith('192'): # The server is running somewhere within the local network. # Local connections don't need portmapping. The following # snippet will retrieve the local ip address. # For example: 192.168.1.3 results_ip = command.get_local_ip() # Assume user is interested in actual network performance # and not a simulated environment. self.init_commands.append(['network', 'real']) else: # If the server is running across the internets, # advertise the public IP of the client so that the # server can send messages back across the internets. # The following snippet will retrieve the public ip address. # For example: 10.3.64.102 # # Keep in mind that for a remote client to receive messages # from a server, the client must first forward the port # at which the server will broadcast messages. # E.g. I am in Sweden, and you are in America. My IP is # s.wed.e.n and your's is a.mer.ic.a. I am listening at port # 1000 and you are sending messages to 1000. But for 1000 to # reach me when coming in from the internet, my router must # first forward any requests for port 1000 to my computer on # local network; e.g. 192.168.1.3:1000 results_ip = command.get_public_ip() # See above self.init_commands.append(['network', 'real']) # Advertise existence of client to server. msg = { command.COMMAND: '_connect', command.ARGS: (UUID, results_ip, results_port), command.ID: UUID } self.requests.send_json(msg) reply = self.requests.recv_json() log.info("Connected") if reply[command.STATUS] != command.OK: print reply[command.INFO] self.results_port = results_port