nanomsg
Home Download Documentation Development Community Support
Getting Started with 'nanomsg'
This document is derived from an original post by Tim Dysinger. That post is no longer available, but we have modified and restructured it, as well as making enhancments and corrections. Tim’s original code is on github, but we recommend using the examples here as they have a number of corrections.
If you want to use the experimental nng library instead, see the document Getting Started with 'nng'.

Pipeline (A One-Way Pipe)

A One-Way Pipe

This pattern is useful for solving producer/consumer problems, including load-balancing. Messages flow from the push side to the pull side. If multiple peers are connected, the pattern attempts to distribute fairly.

pipeline.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <nanomsg/nn.h>
#include <nanomsg/pipeline.h>

#define NODE0 "node0"
#define NODE1 "node1"

void
fatal(const char *func)
{
        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
        exit(1);
}

int
node0(const char *url)
{
        int sock;
        int rv;

        if ((sock = nn_socket(AF_SP, NN_PULL)) < 0) {
                fatal("nn_socket");
        }
        if ((rv = nn_bind(sock, url)) < 0) {
                fatal("nn_bind");
        }
        for (;;) {
                char *buf = NULL;
                int bytes;
                if ((bytes = nn_recv(sock, &buf, NN_MSG, 0)) < 0) {
                        fatal("nn_recv");
                }
                printf("NODE0: RECEIVED \"%s\"\n", buf); (1)
                nn_freemsg(buf);
        }
}

int
node1(const char *url, const char *msg)
{
        int sz_msg = strlen(msg) + 1; // '\0' too
        int sock;
        int rv;
        int bytes;

        if ((sock = nn_socket(AF_SP, NN_PUSH)) < 0) {
                fatal("nn_socket");
        }
        if ((rv = nn_connect(sock, url)) < 0) {
                fatal("nn_connect");
        }
        printf("NODE1: SENDING \"%s\"\n", msg);
        if ((bytes = nn_send(sock, msg, sz_msg, 0)) < 0) {
                fatal("nn_send");
        }
        sleep(1); // wait for messages to flush before shutting down
        return (nn_shutdown(sock, 0));
}

int
main(const int argc, const char **argv)
{
        if ((argc > 1) && (strcmp(NODE0, argv[1]) == 0))
                return (node0(argv[2]));

        if ((argc > 2) && (strcmp(NODE1, argv[1]) == 0))
                return (node1(argv[2], argv[3]));

        fprintf(stderr, "Usage: pipeline %s|%s <URL> <ARG> ...'\n",
                NODE0, NODE1);
        return (1);
}
1 Blithely assumes message is ASCIIZ string. Real code should check it.
Compilation
gcc pipeline.c -lnanomsg -o pipeline
Execution
./pipeline node0 ipc:///tmp/pipeline.ipc & node0=$! && sleep 1
./pipeline node1 ipc:///tmp/pipeline.ipc "Hello, World!"
./pipeline node1 ipc:///tmp/pipeline.ipc "Goodbye."
kill $node0
Output
NODE1: SENDING "Hello, World!"
NODE0: RECEIVED "Hello, World!"
NODE1: SENDING "Goodbye."
NODE0: RECEIVED "Goodbye."
"nanomsg" is a trademark of Garrett D'Amore.