RealityServer Web Services API Programmer's Manual

Protocol Processing

RealityServer Web Services Protocol processing is the final stage in processing an HTTP requests. Protocol handlers are responsible for decoding command requests and encode responses.

Handler selection

Unlike other handlers Protocols are not configured to be used but are selected based on the content of the HTTP request. Each installed protocol is called in turn with the request until one succeeds in deserializing commands. The commands found are executed and then the same protocol used to serialize the results back to the HTTP connection.

Implementation

Protocol handlers are implemented in RealityServer Web Services plugins using the mi::rswservices::IProtocol interface. These are registered with RealityServer Web Services via mi::rswservices::IExtension_context.

Protocol handlers need to implement 3 methods, mi::rswservices::IProtocol::test_request, mi::rswservices::IProtocol::deserialize and mi::rswservices::IProtocol::serialize.
test_request()
test_request is called first on all installed handlers. It should decode as little of the HTTP request as possible and return a confidence value indicating how likely it is that the request is supported by the protocol.
deserialize()
The deserialize() method is called on all handlers in decreasing confidence order. This method should attempt to decode command requests from the HTTP request, populate the command array with requests and return true. If the protocol can not decode the request it should return false and processing will continue to the next protocol.
serialize()
Once command execution is complete the serialize() method is called on the handler which successfully decoded the commands. This method should serialize all command responses back over the HTTP connection to the client.
Note: If any command responses are of type mi::nservices::IBinary then protocol serialization is not used. Instead, the binary data is sent directly to the client.

Types

Protocols come in a wide range of typing strength. REST is a completely untyped protocol where every value is a string, SOAP is strictly typed and JSON-RPC falls somewhere in the middle. For strongly typed protocols this isn't too much of a problem as the protocol handler will know exactly which type to create when setting arguments to commands. For weakly typed ones however there is a problem since the protocol will not know whether an argument should be, for example, a string or a 64 bit float. The neuray Services argument marshaling system overcomes this problem by performing argument conversion just before command execution when argument types are known. To facilitate this, protocols can provide a custom data conversion implementation using mi::rswservices::IProtocol_context::set_converter. This allows protocols specific conversions between types to occur.

RealityServer Web Services provides a default converter which can be obtained using mi::rswservices::IProtocol_context::get_converter. It is recommended that any user implemented converter only provides conversions to and from mi::IString and other types. For other conversions it should simply wrap calls to the default converter.

Built in Protocols

RealityServer Web Services supplies one built in protocol:
  • JSON-RPC version 1 and 2.
This protocol supports JSON-RPC requests POSTed to the server. Alternatively, requests can be made using GET by encoding the JSON-RPC request into the URL argument 'json_rpc_request'. Request parameters must be supplied by-name.

The protocol also contains support for JSONP. The argument used to identify the method to call in the JSONP result must be configured as a 'protocol_json' user configuration in the RealityServer Web Services configuration file. For example:

    <user protocol_json>
    jsonp_argument jsonp
    </user>
    

will enable JSONP for the argument called 'jsonp'. HTTP requests containing this argument will wrap their responses in a call to the function given in the argument. For example:

    http://host:port/?jsonp=process_response&json_rpc_request=....
    

will produce the response

    process_response(RESULT)
    

instead of just RESULT.