This section describes how to do basic eventing using Qeo, i.e. publishing on, and receiving data from, event Topics. It covers the following topics:

Writing Data

The first item you need in order to be able to publish data samples as events is an Event Writer. Creating an event writer is done using the qeo_factory_create_event_writer() function. The method needs four arguments:

  1. The previously created Qeo factory to be used for creating the writer.
  2. The description of the type for which to create a writer.
  3. The listener to be used for policy update notifications (see C).
  4. An optional user data argument.  The user data will be passed back to the application in all listener callback invocations.
Icon

Creation of an event writer for a type that contains key fields will fail and return NULL because events are not allowed to have key fields.

Code Example:

The code snippet below shows you how to:

  • Create an Event Writer which will allow you to write data samples (Events) of type org_qeo_sample_simplechat_ChatMessage_t;
  • Actually publish your data samples.
#include <qeo/api.h>

#include "QSimpleChat_ChatMessage.h"

int main(int argc, const char **argv)
{
    qeo_factory_t *qeo;
    qeo_event_writer_t *msg_writer;

    /* local variables for storing the message before sending */
    char buf[128];
    org_qeo_sample_simplechat_ChatMessage_t chat_msg = { .message = buf };

    /* initialize */
    qeo = qeo_factory_create();
    msg_writer = qeo_factory_create_event_writer(qeo, org_qeo_sample_simplechat_ChatMessage_type,
                                                 NULL, 0);
    /* start conversing */
    while (!done) {
        fgets(buf, sizeof(buf), stdin);
        qeo_event_writer_write(msg_writer, &chat_msg);
    }
    /* clean up */
    qeo_event_writer_close(msg_writer);
    qeo_factory_close(qeo);
    return 0;
} 

Receiving Data

In order to subscribe to, and receive data from, an event Topic, you have to create an Event Reader. More specifically, in our example, we need a reader for instances of type org_qeo_sample_simplechat_ChatMessage_t. Creating a reader is done using the qeo_factory_create_event_reader() function. The function expects four arguments:

  1. The previously created Qeo factory to be used for creating the reader.

  2. The description of the type for which to create a reader (this should be the same as for the corresponding event writer).

  3. The listener to be used for data sample reception and policy update notifications.

  4. An optional user data argument.  The user data will be passed back to the application in all listener callback invocations.

The listener structure can contain two callback functions for data sample reception:

  • (required) the on_data() callback function that will be called whenever there is new data available (in our example of the type org_qeo_sample_simplechat_ChatMessage_t);

  • (optional) the on_no_more_data() callback function that will be called if all received data has been notified to the application and there is no more data at this moment.

There are situations where the on_data() callback function can be called several times in a short period because a burst of samples arrives.  Depending on the application you may want to postpone certain actions until the burst is completely finished (e.g. redrawing a GUI, storing some data in a database, ...).  To be able to do this, you can use the on_no_more_data() callback. This callback is invoked at the end of such a sample burst. It is best practice that the on_data() call should always aggregate samples and the on_no_more_data() should trigger a refresh of the UI. 

Code Example:

In the following code snippet we will show you how to:

  • Create an event reader that allows you to receive data samples of the type org_qeo_sample_simplechat_ChatMessage_t;

  • Implement the reader listener notification callback function on_data().

 

#include <qeo/api.h>

#include "QSimpleChat_ChatMessage.h"

static void on_chat_message(const qeo_event_reader_t *reader,
                            const void *data,
                            uintptr_t userdata)
{
    org_qeo_sample_simplechat_ChatMessage_t *msg = (org_qeo_sample_simplechat_ChatMessage_t *)data;

    /* whenever a new data sample arrives, print it to stdout */
    printf("%s : %s\n", msg->from, msg->message);
}

static qeo_event_reader_listener_t _listener = { .on_data = on_chat_message };

int main(int argc, const char **argv)
{
    qeo_factory_t *qeo;
    qeo_event_reader_t *msg_reader;
    int done = 0;

    /* initialize */
    qeo = qeo_factory_create();
    msg_reader = qeo_factory_create_event_reader(qeo, org_qeo_sample_simplechat_ChatMessage_type,
                                                 &_listener, 0);

    /* start receiving messages */
    while (!done) {
        sleep(60);
    }

    /* clean up */
    qeo_event_reader_close(msg_reader);
    qeo_factory_close(qeo);
    return 0;
}

 

Cleaning up Resources - Closing readers and Writers

Whenever you are done with a reader or a writer you must close it by explicitly calling the qeo_event_reader_close() or qeo_event_writer_close() function respectively. This will release any resources associated with it. Readers and Writers must be closed before the Qeo Factory is closed. Failing to do so can lead to crashes and other problems. Make sure to close all Readers and Writers at all times.