classPiiRemoteObjectServer
#include <PiiRemoteObjectServer.h>
An object that maps QObject's functions and properties into the URI space of a PiiHttpProtocol.
Inherits QObject, PiiHttpProtocol::UriHandler
Description
Usage example
QTimer t; // ... or any other class derived from QObject PiiHttpServer* pHttpServer = PiiHttpServer::addServer("My server", "tcp://0.0.0.0:3142"); PiiRemoteObjectServer* pRemoteObjectServer = new PiiRemoteObjectServer(&t); pHttpServer->protocol()->registerUriHandler("/timer/", pRemoteObjectServer); pHttpServer->start();
See PiiRemoteObjectClient for the client side. If you want the details, read on.
Mapping to URIs
/timer/
/timer/functions/
/timer/functions/start
/timer/functions/stop
/timer/signals/
/timer/signals/timeout
/timer/properties/
/timer/properties/active
/timer/properties/interval
/timer/properties/singleShot
PiiHttpServer is configured so that it returns a list of sub-URIs if no handler is defined for a specific URI. That is, a request to /timer/ would list the root "folders":
GET /timer/ HTTP/1.1
Response:
HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 31 functions/ signals/ properties/
Function calls
GET /timer/functions/ HTTP/1.1
Response:
HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 40 start() start(int) stop()
A call to a function with no parameters is a simple GET request:
GET /timer/functions/start HTTP/1.1
Note that the Host header is not necessary, although HTTP 1.1 dictates one. The response is equally simple (no return value):
HTTP/1.1 200 OK Content-Length: 0
If the function has parameters, they can be specified in the URI:
GET /timer/functions/start?msec=1000 HTTP/1.1
The server requires that parameters are given in the order they are declared in the function signature. It ignores the parameter name, which can therefore be omitted. The example above is equivalent to:
GET /timer/functions/start?1000 HTTP/1.1
Parameters are automatically decoded using PiiHttpDevice::decodeVariant(). If the function has a return value, the same encoding will be used in the return message body.
Properties
GET /timer/properties/ HTTP/1.1
Response:
HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 41 bool active int interval bool singleShot
Individual property values can be retrieved with a GET request to the property URI:
GET /timer/properties/active HTTP/1.1
Response:
HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 4 true
Setting property values may or may not be allowed by the server. The value of an individual property can be set either with a GET or a POST request:
GET /timer/properties/interval?12345 HTTP/1.1 POST /timer/properties/interval HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 15 interval=12345
Many properties can be set at once with either a GET request or a POST (x-www-form-urlencoded) request.
GET /timer/properties?interval=1000&singleShot=false HTTP/1.1 POST /timer/properties HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 30 interval=1000&singleShot=false
Channels and signals
To continue with the timer example, the URI structure in fact contains the following additional entries:
/timer/functions/register
/timer/functions/unregister
/timer/functions/close
/timer/channels/
/timer/channels/new
/timer/channels/reconnect
register(QString id, QString uri) - registers a resource to be pushed to a channel. The first parameter is a channel ID and the second one the URI of a resource (such as a signal). This is equivalent to connecting a slot to a signal.
unregister(QString id, QString uri) - the opposite: the given resource will no longer be pushed through the indicated channel. This is equivalent to disconnecting a slot from a signal.
close(QString) - closes the channel associated with the given channel ID and releases all resources allocated to it.
GET /timer/channels/new HTTP/1.1
Response:
HTTP/1.1 200 OK Content-Type: multipart/mixed-replace; boundary="ural" 4A40938-2229-9F31-D008-2EFA98EC4E6C --ural X-URI: signals/timeout Content-Length: 0 --ural ...
Now that the channel has been set up, one can add pushable resources to the channel. To request the server to push the data emitted through the timeout signal, the following request must be made:
GET /functions/register?4A40938-2229-9F31-D008-2EFA98EC4E6C&/signals/timeout() HTTP/1.1
The first parameter to the register function is the channel ID. The second parameter identifies the pushable resource as a URI. In the case of a signal, the URI must specify the exact signature of the signal to avoid ambiguous overloads. Note that the URI is not percent-encoded in the example for readability although it should really be.
Whenever new registered data becomes available it will be written to the channel. The URI of the resource will be sent as in a non-standard "X-URI" MIME header. The actual data is written in a serialized format (see Serialization library). If the pushed resource is a signal, its parameters will be encoded as a QVariantList. The client and the server must agree on the data format with other pushable resources that may be provided by subclasses.
The reconnect function reconnects the client to a disconnected channel. It takes the channel ID as a parameter. The server keeps unclosed channels in memory for a while allowing clients to recover from network failures. If the channel is still alive, this call will re-establish it as if /channels/new was requested. The only differences are that all previously added pushable resources are still in effect and that the channel ID will not be returned.
Multiple Instances
GET /new HTTP/1.1
Response:
HTTP/1.1 200 OK Content-Length: 35 243F6A8-885A-308D-3131-98A2E0370734
The returned ID can now be used as the URI of the new instance:
GET /243F6A8-885A-308D-3131-98A2E0370734/properties/ HTTP/1.1
Inactive object instances will be kept alive only a limited amount of time. If no accesses have been made to the object for a specified maximum number of milliseconds (see instanceTimeout()), the object will be automatically deleted. If no other requests are made, the instance can be kept alive by requesting /ping. This is a dummy URI whose sole purpose is to indicate the server that the client is still alive. It can also be used to check the availability of a remote object in a non-intrusive manner.
GET /243F6A8-885A-308D-3131-98A2E0370734/ping HTTP/1.1
Response:
HTTP/1.1 200 OK Content-Length: 0
The remote object instance can be explicitly destroyed by requesting /delete:
GET /delete?243F6A8-885A-308D-3131-98A2E0370734 HTTP/1.1
It is possible to pass parameters to the new object instance by encoding them into the request (GET or POST). This makes it possible to even create totally different remote objects based on the parameters. Suppose a server that can create QObjects based on class name. Then, the following request would create an instance of a QTimer.
GET /new?className=QTimer HTTP/1.1
Constructors and destructor
|
Creates a new PiiRemoteObjectServer that maps HTTP request to the given object. |
|
|
Creates a new PiiRemoteObjectServer with no associated server object. |
|
Public member functions
|
Q_INVOKABLE bool
|
|
|
int
|
(
)
Returns the current channel time-out. |
|
Q_INVOKABLE void
|
|
|
Returns the signatures of all invokable functions and slots. |
|
|
virtual void
|
Handles a request. |
|
int
|
(
)
Returns the instance time-out. |
|
int
|
(
)
Returns the maximum number of remote object instances. |
|
Returns a list of accessible property names with their types. |
|
|
Q_INVOKABLE bool
|
|
|
void
|
(
Sets the number of millisecond a channel will be kept alive after a client breaks connection to it without explicitly closing the channel. |
|
void
|
(
Sets the number of millisecond an object instance will be kept alive after a client breaks connection to it without explicitly deleting the instance. |
|
void
|
(
Sets the maximum number of remote object instances the server will manage concurrently. |
|
(
)
Returns the signatures of all signals. |
Protected member functions
|
virtual PiiRemoteObjectServer *
|
(
Returns a new server instance given the parameters passed in the HTTP request. |
|
void
|
Puts data to the send queue of all channels to which the pushable resource identified by uri has been added to. |
|
virtual QStringList
|
Returns a "directory list" of the given folder. |
|
Creates a new PiiRemoteObjectServer with no associated server object. |
Function details
-
PiiRemoteObjectServer
Creates a new PiiRemoteObjectServer that maps HTTP request to the given object.
There will be only one instance of the remote object, and all client requests will use it.
-
PiiRemoteObjectServer
()[protected]Creates a new PiiRemoteObjectServer with no associated server object.
The server will work as a primary server that creates a new secondary server for each client using the createServer() function.
-
~PiiRemoteObjectServer
() -
-
int channelTimeout
()Returns the current channel time-out.
-
Q_INVOKABLE void closeChannel
-
QStringList functionSignatures
()Returns the signatures of all invokable functions and slots.
Each signature contains a return type (if there is one), function name, and a list of parameter types. For example "start(int)" is a valid signature.
-
virtual void handleRequest
[virtual]Handles a request.
This function must be thread-safe.
void MyHandler::handleRequest(const QString& uri, PiiHttpDevice* dev, TimeLimiter*) { // Find the path of the request wrt to the "root" of this handler QString strRequestPath(dev->requestPath(uri)); if (strRequestPath == "index.html" && dev->requestMethod() == "GET") dev->print("<html><head><title>Hello world!</title></head><body><!-- Secret message --></body></html>"); }
Parameters
- uri
the URI the handler was registered at. Use the PiiHttpDevice::requestUri() function to fetch the full request URI.
- dev
the communication device.
PiiHttpProtocolhas already fetched request headers, and the device is positioned at the beginning of request data.- controller
a progress controller. Call the PiiProgressController::canContinue() with no parameters time to time to ensure you are still allowed to continue communication. Returning from this function will automatically flush the output pending in
dev.
Exceptions
- The
function may throw a PiiHttpException on error. PiiHttpProtocol sets the response header correspondingly and writes message to the response body.
Reimplemented from PiiHttpProtocol::UriHandler.
-
int instanceTimeout
()Returns the instance time-out.
-
int maxInstances
()Returns the maximum number of remote object instances.
-
QStringList propertyDeclarations
()Returns a list of accessible property names with their types.
Each entry in this list consists of a type and a property name, e.g. "int value".
-
-
void setChannelTimeout
(- int channelTimeout
Sets the number of millisecond a channel will be kept alive after a client breaks connection to it without explicitly closing the channel.
The default is 10000.
-
void setInstanceTimeout
(- int instanceTimeout
Sets the number of millisecond an object instance will be kept alive after a client breaks connection to it without explicitly deleting the instance.
The default is 10000.
-
void setMaxInstances
(- int maxInstances
Sets the maximum number of remote object instances the server will manage concurrently.
Once this limit is reached, the server will refuse to create new object instances. The default value is 100.
-
QStringList signalSignatures
()Returns the signatures of all signals.
-
virtual PiiRemoteObjectServer * createServer
(- const QVariantMap & parameters
[protected, virtual]Returns a new server instance given the parameters passed in the HTTP request.
If the server is created without an associated server object, this function must be overridden to create a new server object for each client. The default implementation returns 0.
-
Puts data to the send queue of all channels to which the pushable resource identified by uri has been added to.
-
Returns a "directory list" of the given folder.
This function makes it possible for subclasses to add functionality to the default URI tree. If you override this function, add your new entries to the list returned by the default implementation. It is also possible to remove entries from the list.
Parameters
- uri
the URI whose sub-URIs are to be listed, for example "/" or "/functions/".
Returns
a list of sub-URIs. URIs that may contain sub-URIs should end with a slash (/).
Add a note
Not a single note added yet. Be the first, add yours.