def connect(self): ''' Attempts to connect to the server. Returns whether the connection succeeded or not. ''' try: # Create a socket and try to connect to a server. self._socket = socket.socket() self._socket.connect((self._host, self._port)) # Package our Shotgun auth data to then send to the server. authData = {common.AUTH_SERVER: self._sg.config.server, common.AUTH_SCRIPT: self._sg.config.script_name, common.AUTH_KEY: self._sg.config.api_key} dynasocket.send(self._socket, str(authData)) # Get back a message as to whether or not we have succeeded. msg = dynasocket.recv(self._socket) if msg == common.CONNECT_SUCCESS_MSG: self._connected = True elif msg == common.CONNECT_FAIL_MSG: self._connected = False except socket.error: logMsg = common.getLogMessage("Could not connect to server", (self._host, self._port)) logger.warning(logMsg) return self._connected
def run(self): ''' Starts the server watching for messages. This will receive messages and handle them appropriately. Messages are either clients connecting or disconnecting, or a Shotgun transaction request coming in from a client. ''' self._isRunning = True self._needsReInit = True logMsg = common.getLogMessage("DoubleBarrel server started", (self._host, self._port)) self.logger().info(logMsg) while self._isRunning: # Get all of our sockets that have communications occurring. sread, swrite, sexc = select.select(self._clients, [], [], 0.1) #@UnusedVariable for sock in sread: # If the signal is coming from the server socket. if sock == self._socket: # A client is trying to connect. self.acceptNewClient() else: try: # Otherwise, we are receiving a message from the client. msg = dynasocket.recv(sock) if msg: # If we have a message, it is a Shotgun transaction. logMsg = common.getLogMessage("Message received", sock, Message=msg) self.logger().info(logMsg) # Convert our message into a dictionary we can use. funcData = ast.literal_eval(msg) while 1: # Loop until we have a free thread available. if threading.activeCount() < self._maxThreads: ShotgunCommandThread(self._sg, funcData, sock).start() break else: # If there is no message, our client has disconnected. self.disconnectClient(sock) except: self._hasErrored = True self.disconnectClient(sock) # Kill the socket since we are no longer in the loop. logMsg = common.getLogMessage("Stopping server", self._socket) self._socket.close()
def disconnectClient(self, client): ''' Disconnects the client by closing the socket connection and then removing it from the list of active clients. ''' logMsg = common.getLogMessage("Client disconnected", client) self.logger().info(logMsg) client.close() self._clients.remove(client)
def run(self): ''' Performs the Shotgun transaction and then sends the results back through the socket. ''' # Get our function data from the funcdata dict. funcName = self._funcData.get(common.FUNC_NAME) args = self._funcData.get(common.ARGS) kwargs = self._funcData.get(common.KWARGS) results = None # Ensure we have a function name and it exists on the Shotgun object. if funcName and hasattr(self._sg, funcName): queryString = _funcToString(funcName, *args, **kwargs) logMsg = common.getLogMessage("Querying Shotgun", self._socket, Query=queryString) self._logger.info(logMsg) func = getattr(self._sg, funcName) results = func(*args, **kwargs) logMsg = common.getLogMessage("Sending results", self._socket, Results=results) self._logger.info(logMsg) dynasocket.send(self._socket, str(results))
def send(sock, message): """ Sends the message's length, then sends the message. """ try: # Get the message's length. msgLen = len(message) if msgLen > common.BUFFER_SIZE: # Send the message size. sock.send("".join([MESSAGE_LENGTH_STRING, str(msgLen)])) # Wait for confirmation that the message was received. sock.recv(len(CONFIRM_MESSAGE)) # Send the actual message. sock.send(message) except: logMsg = common.getLogMessage("Socket is no longer connected", sock) logger.error(logMsg)
def acceptNewClient(self): ''' Connects a new client by accepting its request and then authorizes it. If it passes authorization, it will add it to the active clients list so we start receiving messages from it. ''' newsock, (host, port) = self._socket.accept() #@UnusedVariable # Create a variable to keep track of if we have failed the connection. failed = False # Get our authorization data. msg = dynasocket.recv(newsock) if msg: authData = ast.literal_eval(msg) server = authData.get(common.AUTH_SERVER) script_name = authData.get(common.AUTH_SCRIPT) api_key = authData.get(common.AUTH_KEY) else: failed = True # Check that our auth data matches our current Shotgun object. if server == self._sg.config.server \ and script_name == self._sg.config.script_name \ and api_key == self._sg.config.api_key: self._clients.append(newsock) self.logger().info(common.getLogMessage("Client Connected", newsock)) dynasocket.send(newsock, common.CONNECT_SUCCESS_MSG) return True else: failed = True if failed: dynasocket.send(newsock, common.CONNECT_FAIL_MSG) newsock.close() return False