| Previous | Menu | Next |
|
To create an annotation server you derive a class from ECS_Annotater and override its receiveRequest() method. The work of receiving a request, dissassembling it, and constructing a response is all done within this method. Requests are received by receiveRequest() as instances of the ECS_AnnoRequest class. Methods are provided to determine the source of the request, its expiry time, to obtain the request details, and for responding to the request. The request details are encapsulated in an instance of the ECS_AnnoData class, which contains the list of data sent by the Annotation node. The list of data is in turn enclosed in an instance of the class ECS_AttrValueList. Values are extracted from the ECS_AttrValueList using the methods getInteger(), getReal(), getBool(), and so on. Since you must know the type of an attribute before you can extract it, you call the method typeOfNthItem() to find out the data type of a specified element in the list (list elements are numbered from 1). Repeated calls to the various get... methods on the ECS_AttrValueList are used to extract all the values needed to construct a response. After computing a result from the request, which may involve calling other processes such as querying a database, a response can then be assembled. The response can be assembled in a variety of ways:
The constructed ECS_AnnoData response is then sent using the respond() method of the corresponding request instance, and the receiveRequest() method returns. Source code sample:
.
.
.
class myServer : public ECS_Annotater
{
public:
myServer() { n = 0; m = 0; };
int32 receiveRequest(ECS_AnnoRequest request);
private:
int32 n;
int32 m;
};
int32 myServer::receiveRequest(ECS_AnnoRequest request)
{
const ECS_AnnoData& data = request.getData();
if ((data.size() == 2)
&& (data.typeOfNthItem(1) == EV_INTEGER)
&& (data.typeOfNthItem(2) == EV_INTEGER))
{
const int32* int1 = data.getInteger(1);
const int32* int2 = data.getInteger(2);
cout << "Server 1: - Received annotation request from "
<< request.getAnnoNodeName() << " in circuit "
<< request.getCircuitName()
<< " (seq # = "
<< request.getSequenceNumber()
<< ", exp time = "
<< request.getExpiryTime()
<<endl;
cout << "\twith int1 = "
<< *int1
<< ", int2 = "
<< *int2
<< endl;
int32 reply = *int1 + *int2;;
ECS_AnnoData response;
response.setValue(2, reply);
request.respond(response);
}
else
{
cout << "Server 1: Request data not matched" << endl;
// Invalid request - ignore
request.reject();
}
return 0;
}
// --------- The main program ---------
int
main(int argc, char* argv[])
{
int32 instance = 1;
.
.
.
signal(SIGTERM, exitHandler);
signal(SIGINT, exitHandler);
// Create a handle for engine instance 1
ECS_Engine engine(instance);
// Create an instance of the event output handler class
myServer server;
ECS_AnnoFilter filter(0, "anno1");
server.setFilter(filter);
// Register the output handler instance with the engine
engine.addAnnotater(server);
// Enter the main loop. This call will block until
// ECS::shutdown is called; use ECS::poll() for a
// non-blocking call.
ECS::mainloop();
return 0;
}
|