 |
» |
|
|
 |
A program that subscribes for receiving event notifications
must perform the following operations: Create
a listening connection to the EVM daemon Communicate to the daemon which events it is interested
in by passing a filter string Monitor event activity on the connection, and be
prepared to handle each event as it arrives
Example 4-6 “ Subscribing for
Event Notification” shows
how to wait for events to arrive, and display each incoming event
on stdout. Example 4-6 “ Subscribing for
Event Notification” introduces
the following functions:
EvmConnSubscribe — Requests
notification of any posted events that match the supplied filter. For
more information about this function, see EvmConnSubscribe(3). EvmConnWait — Blocks
until activity is detected on a specified connection. When activity
is detected, the calling program can call EvmConnDispatch() to handle the activity. For more information about this
function, see EvmConnWait(3). EvmConnDispatch — Handles
any outstanding I/O on a specified connection by calling the program's
callback function as per requirements. For more information about
this function, see EvmConnDispatch(3). EvmEventFormat — Formats
an event. For more information about this function, see EvmEventFormat(3).
 |  |  |  |  | NOTE: You can use the simpler EvmConnCreateSubscriber() macro in place of EvmConnCreate() to create a subscribing connection. This macro requires
fewer arguments than EvmConnCreate(). Although it offers fewer connection options, it is
suitable for use by most subscribing applications. For more information
about this function, see EvmConnCreate(3). |  |  |  |  |
Example 4-6 Subscribing for
Event Notification  |
#include <stdio.h>#include <evm/evm.h>void EventCB(EvmConnection_t conn, EvmCallbackArg_t cbarg, EvmCallbackData_t *cbdata);/*====================================================* Function: main()*====================================================*/int main(){ EvmConnection_t conn; EvmStatus_t status; /* Use EvmConnCreate() to establish a connection to the EVM daemon, this time specifying a listening connection. The following arguments appear in this code segment: The first two arguments to EvmConnCreate() specify that the connection will be used for listening and notifying events, through a callback function. The third argument, NULL indicates that you are making a connection to the local EVM daemon. The fourth argument specifies the callback function to be called when events arrive---- EventCB is the next function. The fifth argument is the callback argument--- a value that will be passed to the callback function each time it is called to service this connection. You can use this argument for anything you want, but in this example it is just set to NULL. The final argument receives the handle to the connection.*/ status = EvmConnCreate(EvmCONNECTION_LISTEN, EvmRESPONSE_CALLBACK, NULL,EventCB,NULL,&conn); if (status != EvmERROR_NONE) { fprintf(stderr,"Failed to create EVM listening connection\n"); exit(1); } /* The next step is to use the EvmConnSubscribe() function to let the EVM daemon know which events you are interested in receiving. In this case, you will watch for user messages that can be posted with evmpost. These events have the name sys.unix.evm.msg.user. Note that calling EvmConnSubscribe() results in your callback function being invoked with a reason code of EvmREASON_SUBSCRIBE_COMPLETE when you call EvmConnDispatch() function. */ status = EvmConnSubscribe(conn,NULL,"[name *.evm.msg.user]"); if (status != EvmERROR_NONE) { fprintf(stderr,"Failed to subscribe for event notification\n"); exit(1); } /* This example does not have anything to do except wait for arriving events, so it loops forever, using EvmConnWait() to watch for activity on the connection. Passing NULL as the second argument to EvmConnWait() indicates that you do not want to time out if there is no activity. EvmConnWait() will return each time any activity occurs b not always because an event has arrived. For example, the EVM daemon may have sent some other message or the process may have been interrupted by a signal. Each time the function returns without error, you must call EvmConnDispatch() to handle the activity. This will usually (but not always) result in EventCB(), the callback function, being called. */ for (;;) { status = EvmConnWait(conn,NULL); if (status != EvmERROR_NONE) { fprintf(stderr,"Connection error\n"); exit(1); } if (EvmConnDispatch(conn) != EvmERROR_NONE) { fprintf(stderr,"Connection dispatch error\n"); exit(1); } }}/*====================================================* Function: EventCB()*====================================================*//* The callback function is called by EvmConnDispatch() whenever it reads a message from the daemon that needs to be handled by application code. This includes incoming events; remember, however, that you may need to consider other types of messages in your application. The following arguments appear in this code segment: The first argument to the callback function is the connection handle. This is useful to identify the connection in some circumstances, but you may find that you do not have a use for it. The second argument is the callback argument that you supplied when you established the connection. You may choose to use this value to identify the connection, or (in C++ code) to pass a pointer to an object instance, or you may not use it at all. The final argument is the callback data, a pointer to a structure containing information about the callback. The code must examine the callback data structure to find out why it was called. The structure includes a reason code, a status value, and (if an event is being delivered) a pointer to the event. See EvmCallback (5) for details about the structure. In this example, you are looking for incoming event messages, indicated by the EvmREASON_EVENT_DELIVERED reason code. As each event comes in, you format and display it, and then (because you are responsible for the space it consumes) destroy it after you are done with it.*/void EventCB(EvmConnection_t conn, EvmCallbackArg_t cbarg, EvmCallbackData_t *cbdata){ char buff[256]; /* The action taken always depends on the reason for the callback. In this case, the reason is event delivered, so you use the EvmEventFormat() function to format the event for display, and then you print it to stdout. The EvmEventFormat() produces a text line that is formed from the event's format data item (if present), and places the result in the buffer that you supply. Formatting does not cause the event itself to change. */ switch (cbdata->reason) { case EvmREASON_EVENT_DELIVERED: EvmEventFormat(buff, sizeof(buff), cbdata->event); fprintf(stdout,"Event: %s\n",buff); /* The delivered event is using heap space, and it is the responsibility of the application to free the space after it has finished with the event. */ EvmEventDestroy(cbdata->event); break; /* Because we made a subscription request earlier, the function will also be invoked with a callback reason of EvmREASON_SUBSCRIBE_COMiPLETE. In this example, all the reason codes can be ignored.*/ default: break; }} |
 |
|