Just a second...

Start subscribing with C

Create a C client within minutes that connects to Diffusion™ Cloud. This example creates a client that prints the value of a topic to the console when the topic is updated.

The C client libraries rely on a number of dependencies. Depending on which platform you are using the C client libraries for, these dependencies might be included in the client library. If they are not included in the client library, ensure that the dependencies are available on your development system.

For more information about dependencies on each supported platform, see C.

The C client library statically links to Apache Portable Runtime (APR) version 1.5 with APR-util. Ensure that you set APR_DECLARE_STATIC and APU_DECLARE_STATIC before you use any APR includes. You can set these values in the following ways:
  • By including diffusion.h before any APR includes. The diffusion.h file sets these values.
  • As command-line flags
For more information, see http://apr.apache.org

To complete this example, you need a Diffusion Cloud service. For more information about getting a Diffusion Cloud service, see Getting started with Diffusion Cloud.

You also require either a named user that has a role with the select_topic and read_topic permissions or that anonymous client connections are assigned a role with the select_topic and read_topic permissions. For example, the "CLIENT" role. For more information about roles and permissions, see Role-based authorization.

This example steps through the lines of code required to subscribe to a topic. The full code example is provided after the steps.
  1. Get the Diffusion Cloud C client library for your platform and extract the ZIP file.
    The C client library is available from http://download.pushtechnology.com/cloud/latest/sdks.html.
  2. Create a C file called getting-started.c.
    1. Include the following libraries:
      #include <stdio.h>
      #include <unistd.h>
      
      #include "diffusion.h"
      #include "args.h"
    2. Create a main method:
      int
      main(int argc, char **argv)
      {
      
      }
  3. Create a connection to Diffusion Cloud.
    Inside the main method add the following lines:
            /*
             * Create a session
             */
            DIFFUSION_ERROR_T error = { 0 };
            SESSION_T *session = NULL;
            // Edit this line to include the host and port of your Diffusion server
            session = session_create("ws://service-name.diffusion.cloud:80", "user", credentials_create_password("password"), NULL, NULL, &error);
            if(session == NULL) {
                    fprintf(stderr, "TEST: Failed to create session\n");
                    fprintf(stderr, "ERR : %s\n", error.message);
                    return EXIT_FAILURE;
            } else {
                    fprintf(stdout, "Connected\n");
            }
    Where service-name is the name of your Diffusion Cloud service, user is the name of a user with the permissions required to subscribe to a topic, and password is the user's password.
    The client logs the string "Connected" to the console if the connection is a success.
  4. Subscribe to the topic foo/counter.
    1. Above the main method, create a callback for when subscription occurs.
      static int
      on_subscribe(SESSION_T *session, void *context_data)
      {
              printf("Subscribed to topic\n");
              return HANDLER_SUCCESS;
      }
      This callback prints a message to the console when the client subscribes to the foo/counter topic.
    2. Above the main method, create a callback for when an update is received.
      static int
      on_topic_message(SESSION_T *session, const TOPIC_MESSAGE_T *msg)
      {
              printf("%.*s\n", (int)msg->payload->len, msg->payload->data);
              return HANDLER_SUCCESS;
      }
      This callback prints the value of the topic to the console every time the foo/counter topic is updated.
    3. In the main method, call the subscribe method.
              subscribe(session, (SUBSCRIPTION_PARAMS_T) { .topic_selector =  ">foo/counter", .on_topic_message = on_topic_message, .on_subscribe = on_subscribe });
  5. Set the client to wait for 5 minutes before closing.
           /*
             * Receive messages for 5 minutes.
             */
            sleep(300);
    
            session_close(session, NULL);
            session_free(session);
    
            return EXIT_SUCCESS;
  6. Build your C client.
    1. Create a Makefile in the same directory as your C file.
      An example Makefile is provided after the steps.
    2. Ensure that your Makefile links to the include and lib directory of the Diffusion Cloud C library.
      DIFFUSION_C_CLIENT_INCDIR	= ../path-to-client/include
      DIFFUSION_C_CLIENT_LIBDIR	=  ../path-to-client/lib
    3. Run the make command to build the example.
      The getting-started binary is created in the target/bin directory.
  7. Run your C client from the command line.

The client prints a the value to the console every time the value of the foo/counter topic is updated. You can update the value of the foo/counter topic by using the Diffusion Cloud Dashboard's test client or by creating a publishing client to update the topic. To create and publish to the foo/counter topic, you require a user with the modify_topic and update_topic permissions. For more information, see Start publishing with C.

The completed getting-started.c file contains the following code:
#include <stdio.h>
#include <unistd.h>

#include "diffusion.h"
#include "args.h"

/*
 * When a subscribed message is received, this callback is invoked.
 */
static int
on_topic_message(SESSION_T *session, const TOPIC_MESSAGE_T *msg)
{
        printf("%.*s\n", (int)msg->payload->len, msg->payload->data);
        return HANDLER_SUCCESS;
}

/*
 * This callback is fired when Diffusion responds to say that a topic
 * subscription request has been received and processed.
 */
static int
on_subscribe(SESSION_T *session, void *context_data)
{
        printf("Subscribed to topic\n");
        return HANDLER_SUCCESS;
}

int
main(int argc, char **argv)
{

        /*
         * Create a session
         */
        DIFFUSION_ERROR_T error = { 0 };
        SESSION_T *session = NULL;
         // Edit this line to include the URL of your Diffusion Cloud service
        session = session_create("ws://service-name.diffusion.cloud:80", "user", credentials_create_password("password"), NULL, NULL, &error);
         
        if(session == NULL) {
                fprintf(stderr, "TEST: Failed to create session\n");
                fprintf(stderr, "ERR : %s\n", error.message);
                return EXIT_FAILURE;
        } else {
                fprintf(stdout, "Connected\n");
        }

        subscribe(session, (SUBSCRIPTION_PARAMS_T) { .topic_selector =  ">foo/counter", .on_topic_message = on_topic_message, .on_subscribe = on_subscribe });

        /*
         * Receive messages for 5 minutes.
         */
        sleep(300);

        session_close(session, NULL);
        session_free(session);

        return EXIT_SUCCESS;
}
The Makefile contains the following code:
# The following two variables must be set.
#
# Directory containing the C client include files.
DIFFUSION_C_CLIENT_INCDIR	= ../path-to-client/include
#
# Directory containing libdiffusion.a
DIFFUSION_C_CLIENT_LIBDIR	=  ../path-to-client/lib

ifndef DIFFUSION_C_CLIENT_INCDIR
$(error DIFFUSION_C_CLIENT_INCDIR is not set)
endif

ifndef DIFFUSION_C_CLIENT_LIBDIR
$(error DIFFUSION_C_CLIENT_LIBDIR is not set)
endif

CC		= gcc

# Extra definitions from parent directory, if they exist.
-include ../makefile.defs

CFLAGS		+= -g -Wall -Werror -std=c99 -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=700 -c -I$(DIFFUSION_C_CLIENT_INCDIR)
LDFLAGS		+= $(LIBS) $(DIFFUSION_C_CLIENT_LIBDIR)/libdiffusion.a -lpthread -lpcre -lssl -lcrypto

ARFLAGS		+=
SOURCES = getting-started.c

TARGETDIR	= target
OBJDIR		= $(TARGETDIR)/objs
BINDIR		= $(TARGETDIR)/bin
OBJECTS		= $(SOURCES:.c=.o)
TARGETS = getting-started

all:		prepare $(TARGETS)
.PHONY:		all

prepare:
		mkdir -p $(OBJDIR) $(BINDIR)

$(OBJDIR)/%.o:	%.c
		$(CC) $(CFLAGS) -o $@ $<

getting-started:	$(OBJDIR)/getting-started.o
		$(CC) $< $(LDFLAGS) -o $(BINDIR)/$@

clean:
		rm -rf $(TARGETS) $(OBJECTS) $(TARGETDIR) core a.out