Universal Messaging 10.3 | Developer Guide | Enterprise APIs | Enterprise Developer's Guide for C++ | Publish / Subscribe using Channel Topics | Durable channel consumers
 
Durable channel consumers
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.
Asynchronous Durable Consumer
An example of how to create a durable subscription 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 durable subscription 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 durable subscription that begins from event ID 0, is 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 durable subscriptions. 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();
}