Beispiel #1
0
    def send_message_blocking(self, message):
        """
        Call from another thread to send a message to the server and wait for the result.
        Accepts a serializable message.
        Based on the response either the result is returned or an exception is raised.

        Parameters
        ----------
        message : :class:`quartjes.connector.messages.Message`
            Message object to send to the server.
        
        Returns
        -------
        result
            The response returned by the server.
            
        Raises
        ------
        MessageHandleError
            Something went wrong while handling the message on the server.
        ConnectionError
            There is an issue with the connection to the server.
        TimeoutError
            No response was received within the set timeout.
        """
        serial_message = create_message_string(message)
        try:
            result_msg = threads.blockingCallFromThread(reactor, self._r_send_message_and_wait, message.id, serial_message)
            if result_msg.result_code > 0:
                raise MessageHandleError(error_code=result_msg.result_code, error_details = result_msg.result)
            return result_msg.result
        except TimeoutError:
            self._waiting_messages.pop(message.id, None)
            raise
Beispiel #2
0
 def _r_send_error(self, result, protocol):
     """
     Send an exception to the client.
     This is the only method that creates XML inside the reactor thread. This
     might cause problems if the error contains a lot of data, but for now we
     do not expect this to be the case.
     
     Parameters
     ----------
     result
         Result from twisted encapsulating an exception.
     protocol
         Twisted protocol object connected to the client that should receive
         event notifications.
     
     Raises
     ------
     Exception
         If the exception received is not of type 
         :class:`quartjes.connector.exceptions.MessageHandleError` we reraise the
         exception instead of sending it to the client.
     """
     error = result.value
     if not isinstance(error, MessageHandleError):
         raise error
     print("Error occurred: %s" % result)
     msgid = None
     if error.original_message is not None:
         msgid = error.original_message.id
     msg = ResponseMessage(result_code=error.error_code, response_to=msgid, result=error.error_details)
     protocol.send_message(create_message_string(msg))
Beispiel #3
0
    def _parse_message(self, string, protocol):
        """
        Parse the contents of a message. Also do processing outside the reactor
        thread.

        This method should run in a separate thread to prevent blocking the reactor.

        Both the parsed original message and a possible return message are returned
        in a special MessageResult instance.
        
        Parameters
        ----------
        string : string
            Incoming message string to handle.
        protocol
            Twisted protocol object connected to the client.
            
        Returns
        -------
        result : :class:`MessageResult`
            Result of parsing the message.
        
        Raises
        ------
        MessageHandleError
            If any error occurs while handling the message.
        """
        #print("Parsing message: %s" % string)
        msg = parse_message_string(string)
        result = MessageResult(original_message=msg)

        if isinstance(msg, MethodCallMessage):
            # Handle method call
            res = self._method_call(msg)
            response_msg = ResponseMessage(result_code=0, result=res, response_to=msg.id)
            result.response = create_message_string(response_msg)
        elif isinstance(msg, SubscribeMessage):
            # Handle subscription to event
            response_msg = ResponseMessage(result_code=0, result=None, response_to=msg.id)
            result.response = create_message_string(response_msg)
        else:
            raise MessageHandleError(MessageHandleError.RESULT_UNEXPECTED_MESSAGE, msg)

        return result
Beispiel #4
0
 def _r_successful_connection(self):
     """
     Handle a succesful connection. Resets the reconnect backoff and makes
     sure all events that were already subscribed to are active again.
     """
     self.resetDelay()
     for (service_name, event_name) in self._event_callbacks.keys():
         msg = SubscribeMessage(service_name=service_name, event_name=event_name)
         serial_message = create_message_string(msg)
         self._current_protocol.send_message(serial_message)
Beispiel #5
0
    def test_create_and_parse(self):
        """
        Test whether a message can be correctly serialised and deserialised again.
        """
        string = create_message_string(self.message)
        self.assertIsNotNone(string)
        self.assertGreater(len(string), 0)

        result = parse_message_string(string)
        self.assertEqual(self.message, result)
Beispiel #6
0
    def test_create_and_parse(self):
        """
        Test whether a message can be correctly serialised and deserialised again.
        """
        string = create_message_string(self.message)
        self.assertIsNotNone(string)
        self.assertGreater(len(string), 0)

        result = parse_message_string(string)
        self.assertEqual(self.message, result)
Beispiel #7
0
 def _r_on_connection_established(self, protocol):
     """
     Handle an incoming connection.
     
     Parameters
     ----------
     protocol
         Twisted protocol object connected to the client.
     """
     self._connections[protocol.id] = protocol
     motd = ServerMotdMessage(client_id=protocol.id)
     protocol.send_message(create_message_string(motd))
Beispiel #8
0
 def send_event(self, service_name, event_name, listener, *pargs, **kwargs):
     """
     Notify a client of an event.
     
     Parameters
     ----------
     service_name : string
         Name of the service firing the event.
     event_name : string
         Name of the event being fired.
     listener
         Twisted protocol object connected to the client that should receive
         event notifications.
     *pargs
         Any additional positional arguments will be sent as positional
         arguments to the client callback.
     **kwargs
         Any additional keyword arguments will be sent as keyword
         arguments to the client callback.
         
     """
     msg = EventMessage(service_name, event_name, pargs, kwargs)
     string = create_message_string(msg)
     reactor.callFromThread(listener.send_message, string) #@UndefinedVariable