[nanomsg] Re: publish/subscribe keys

  • From: "John Carneiro" <johncarneiro@xxxxxxxxxxx>
  • To: <nanomsg@xxxxxxxxxxxxx>
  • Date: Thu, 14 Aug 2014 08:08:38 -0400

OK, thanks for the help.

This makes it a little more difficult as I use google protobufs
to serialize the messages in binary prior to being sent, but
if I understand it correctly, I could prefix the binary serialization with
the ascii text subscription tag.

I reworked the example below to follow what is suggested.
Is this the correct way to prefix the message on the server code?

I may need an extra \0 between the sub tag and data:
so, instead of this
sprintf (buf1, "%s%s", sub1, d);
do this
sprintf (buf1, "%s\0%s", sub1, d);

Let me know. Thanks !

-

#include <assert.h>
#include <stdio.h>
#include "../src/nn.h"
#include "../src/pubsub.h"
#include "string.h"

#define SERVER "server"
#define CLIENT "client"

char *date ()
{
 time_t raw = time (&raw);
 struct tm *info = localtime (&raw);
 char *text = asctime (info);
 text[strlen(text)-1] = '\0'; // remove '\n'
 return text;
}

int server (const char *url)
{
 int sock = nn_socket (AF_SP, NN_PUB);
 assert (sock >= 0);
 assert (nn_bind (sock, url) >= 0);

 while (1)
 {
   const char* sub1 = "sub1";
   char *d = date();
   char buf1[100];
   sprintf (buf1, "%s%s", sub1, d);
   int sz_buf1 = strlen(buf1) + 1; // '\0' too
   printf ("SERVER: PUBLISHING sub1 %s\n", d);
   int bytes1 = nn_send (sock, buf1, sz_buf1, 0);
   assert (bytes1 == sz_buf1);

   const char* sub2 = "sub2";
   const char *test = "test123";
   char buf2[100];
   sprintf (buf2, "%s%s", sub2, test);
   int sz_buf2 = strlen(buf2) + 1; // '\0' too
   printf ("SERVER: PUBLISHING sub2 %s\n", test);
   int bytes2 = nn_send (sock, buf2, sz_buf2, 0);
   assert (bytes2 == sz_buf2);

   sleep(1);
}

return nn_shutdown (sock, 0);

}

int client (const char *url, const char *name)
{
int sock = nn_socket (AF_SP, NN_SUB);
assert (sock >= 0);

const char* subType = "sub1";
assert (nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, subType,
strlen(subType) + 1) >= 0);
assert (nn_connect (sock, url) >= 0);
while (1)
  {
  char *buf = NULL;
  int bytes = nn_recv (sock, &buf, NN_MSG, 0);
  assert (bytes >= 0);
  printf ("CLIENT (%s): RECEIVED %s\n", name, buf);
  nn_freemsg (buf);
  }
return nn_shutdown (sock, 0);
}

int main (const int argc, const char **argv)
{
if (strncmp (SERVER, argv[1], strlen (SERVER)) == 0 && argc >= 2)
  return server (argv[2]);
else if (strncmp (CLIENT, argv[1], strlen (CLIENT)) == 0 && argc >= 3)
  return client (argv[2], argv[3]);
else
  {
  fprintf (stderr, "Usage: pubsub %s|%s <URL> <ARG> ...\n",
       SERVER, CLIENT);
  return 1;
  }
}

-----Original Message----- From: Dirkjan Ochtman
Sent: Wednesday, August 13, 2014 6:08 PM
To: nanomsg
Subject: [nanomsg] Re: publish/subscribe keys

On Wed, Aug 13, 2014 at 9:47 PM, John Carneiro <johncarneiro@xxxxxxxxxxx> wrote:
It seems like this line from the example:
nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, "", 0)

could easily be instead something like this to subscribe to a subscription
type of "sub1":
const char* subType = "sub1";
nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, subType, strlen(subType) + 1)

Yes, that's about right.

and I would assume you could read this string on the publishing server like
this
char subType[100];
getsockopt(sock, NN_SOL_SOCKET, NN_PROTOCOL, &subType, sizeof(subType));

But that is not. For now, subscriptions on the NN_SUB side of the
protocol (there may be more than one, theoretically as many as you
like) are matched against the actual message sent by the NN_PUB side.
So, if you're subscribing to "sub1\0", a message containing "sub1\0a"
from the publisher will be received, whereas a message containing
"sub2" will not.

Hopefully that's enough information to get your example working, do
ask more questions if that turns out not to be the case.

Cheers,

Dirkjan

Other related posts: