Durable channel consumers and named objects
Universal Messaging provides the ability for both asynchronous and synchronous consumers to be durable. Durable consumers allow state to be kept at the server with regard to what events have been consumed by a specific consumer of data.
Universal Messaging supports durable consumers through use of Universal Messaging named objects as shown by the following example code.
Names objects can also be managed via the enterprise manager.
Asynchronous Durable Consumer
An example of how to create a named object that begins from event id 0, is persistent and is used in conjunction with an asynchronous event consumer:
class mySubscriber : public nEventListener {
public:
mySubscriber(){
// construct your session
// and channel objects here
// create the named object and begin consuming events from the channel at event id 0
// i.e. the beginning of the channel
nNamedObject *nobj = myChannel->createNamedObject("unique1", 0, true);
myChannel->addSubscriber(this , nobj);
}
void go(nConsumeEvent *event) {
printf("Consumed event %d",event->getEventID());
}
int main(int argc, char** argv) {
new mySubscriber();
return 0;
}
}
Synchronous Durable Consumer
An example of how to create a named object that begins from event id 0, persistent and is used in conjunction with a synchronous event consumer:
class myIterator {
private:
nChannelIterator *iterator = null;
public:
myIterator(){
// construct your session
// and channel objects here
// start the iterator at the beginning of the channel (event id 0)
nNamedObject *nobj = myChannel->createNamedObject("unique2", 0, true);
iterator = myChannel->createIterator(0);
}
void start() {
while (true) {
nConsumeEvent *event = iterator->getNext();
go(event);
}
}
void go(nConsumeEvent *event) {
printf("Consumed event %d",event->getEventID());
}
int main(int argc, char** argv) {
myIterator *itr = new myIterator();
itr->start();
return 0;
}
}
Both synchronous and asynchronous channel consumers allow message selectors to be used in conjunction with named objects. Please see the API documentation for more information.
There are also different ways in which events consumed by named consumers can be acknowledged. By specifying that 'auto acknowledge' is true when constructing either the synchronous or asynchronous consumers, then each event is acknowledged as consumed automatically. If 'auto acknowledge' is set to false, then each event consumed has to be acknowledged by calling the ack() method:
void go(nConsumeEvent *event) {
printf("Consumed event %d",event->getEventID());
event->ack();
}