psmq_overview(7)

bofc manual pages

psmq_overview(7)



 

NAME

psmq - publish subscribe message queue  

SYNOPSIS

psmq - is a set of programs and libraries to implement publish/subscribe communication over POSIX message queues.

This page shortly describes each component of the tool and more information about each component can be found on their own pages.  

DESCRIPTION

 

LIBRARY USAGE

/* only single header is needed */
#include <psmq.h>

int main(void)
{
    struct psmq  *psmq; /* psmq library object, passed to all psmq functions */
    struct psmq_msg  msg; /* struct that holds received message from broker */

    /* Library is very easy to use, at first you need to
     * initialize library object and connect to the broker */
    psmq_init(&psmq, "/broker-queue", "/our-queue", 10);

    /* now you are ready publish messages */
    psmq_publish(&psmq, "/topic", "data", strlen("data") + 1, 0);

    /* if you want to receive messages you need to
     * first subscribe to a topic */
    psmq_subscribe(&psmq, "/engine/rpm");
    /* you can subscribe to as many topics as you'd like */
    psmq_subscribe(&psmq, "/wheel/speed");

    /* now you can start receiving data */
    psmq_receive(&psmq, &msg, NULL);

    return 0;
}

And that's all about basic usage. You can use PSMQ_TOPIC and PSMQ_PAYLOAD macros to easily extract topic and payload from msg without knowing its internal structure. More on this with usage example can be found in psmq_receive(3).  

PUBLISH/SUBSCRIBE

The psmq communication is based on the publish subscribe principle. Multiple clients can connect to the broker. Any client can subscribe to any ammount of topics and any client can send message to any topic. Such message will be received by all clients that are subsribed to the topic. It is perfectly ok for many clients to subsribe to same topic as for many clients to send message to same topic. One client can be both subscriber and publisher simultaneously.  

TOPICS

As described earlier, clients communicate with each other sending and receiving messages on specific topic. Topic is simple c-string that starts with '/' character. Altough topic is string, and may contain non-printable characters it is advisible to use only printable chars and no spaces, it will be easier later to read/debug such messages.

Topics are in form of hierarchy, very similar to UNIX paths. So every topic should begin with '/' character, and each category should be delimited with '/' character as well. Some examples can be:

    /engine/2/rpm
    /engine/2/power
    /can/room/142/kitchen/temperature
    /can/room/142/bedroom/temperature
    /voltage

You can use any structure that best suits your needs.

While both publishers and subscribers can use full form of topics, only subsribers can use wildcards to subscribe to multiple topics with one subscription. There are 2 wildards.

First one is + (plus) character. It can be used to accept anything that may show in one part of structure. Let's look back at examples of topic. If we want to subsribe to read temperature in every hotel room, but only in the kitchen, we need to subscribe to

    /can/room/+/kitchen/temperature

Should we need to read temperature in all hotel rooms, in all rooms, we will subscribe to

    /can/room/+/+/temperature

We can put wildcards in any place in structure. To subscribe to every sensor in all hotel rooms in bedrooms, subscribe to this:

    /can/room/+/bedroom/+

Or get all sensors from all hotel rooms

    /can/room/+/+/+

For this wildcard to work, plus character must be alone, that is "/can/room+/+" will treat "room+" part as standard topic and not wildcard. Some more examples, for message sent on topic "/a/b/c/d" following subscriptions will match

    /a/b/c/d
    /a/+/c/d
    /a/b/c/+
    /+/b/c/+
    /+/+/+/+
    /a/+/b/+

But these will not match:

    /a/b/c
    /a/b/+
    /a/b/c/+/e
    /a/b/c/d/+
    /+/+/+/+/e

Note, that above wildcard will not receive sensor if structure differs a bit, and sensor value is sent on topic "/can/room/142/kitchen/fridge/temperature". If structure is not regular, you might be better of with another wildcard.

Another type of wildcard is * (star) character. This allows to accept rest of the topic from the wildcard till the end. So to subscribe to all sensors from all hotel rooms, instead of putting 3 plus wildcards, we can use this:

    /can/room/*

Now, we will receive every topic that starts from "/can/room/" (but we won't receive message send directly to "/can/room"). With this wildcard, we will receive all informations from all rooms, regardless of how many part structure has. Some more examples, for message sent on topic "/a/b/c/d" following subscriptions will match

    /a/b/c/*
    /a/*
    /*

and "/a/b/c/d/*" will not match. "/*" subscription will effectively match all messages.

For this wildcard to work, star character must be alone at the very end of topic, otherwise it will be treated as ordinary topic.

Wildcards can also be mixed together. So, assuming irregular sensor structure in kitchen, to receive information from all sensor in all kitches, it would be best to use

    /can/room/+/kitchen/*

This will match both "/can/room/+/kitchen/temperature" and "/can/room/+/kitchen/fridge/temperature".

A quick summary for topic rules:

* topic is a standard c-string, all characters but null '\0' are allowed
* topic must start with '/' (slash) character
* topic must not end with '/' (slash) character
* empty parts of topic (like /a//c) are not allowed
* for wildcards to work, they must be the only character in single topic part
* '+' (plus) wildcard, can be places anywhere
* '*' (star) wildcard, must be last character in the topic  

BROKER

psmqd(1) is a main daemon application which functions as a broker for the clients. It receives messages from the clients and relays messages to all clients that subscribed to specified topic.  

LIBRARY

libpsmq is a helper library that can be used by clients to make it easy to send and receive messages from/to broker. Following functions are available

psmq_init(3)initializes psmq object and connects to the broker
psmq_cleanup(3)cleanup whatever has been allocated by init
psmq_publish(3)publishes message on given topic
psmq_receive(3)receive single message from the broker
psmq_timedreceive(3)as above but return after timeout with no message
psmq_timedreceive_ms(3)as above but accepts [ms] instead of timespec
psmq_subscribe(3)subscribe to given topic to receive data
psmq_unsubscribe(3)unsubscribe from topic to not receive that data
psmq_ioctl(3)alter how broker communicates with client
 

PROGRAMS

psmq-pub(1) This helper program allows to send multiple messages to specified broker directly from the command line. It is useful for debugging or sending messages from the scripts.

psmq-sub(1) This helper program allows to receive multiple messages from specified broker directly from the command line. It is useful for debugging or as a traffic logger.  

BUG REPORTING

Please, report all bugs to "Michał Łyszczek <michal.lyszczek@bofc.pl>"  

SEE ALSO

psmqd(1), psmq-pub(1), psmq-sub(1), psmq_cleanup(3), psmq_init(3), psmq_publish(3), psmq_receive(3), psmq_subscribe(3), psmq_timedreceive(3), psmq_timedreceive_ms(3), psmq_unsubscribe(3), psmq_building(7), psmq_overview(7).

bofc.pl

19 May 2021 (v9999)

psmq_overview(7)