nanomsg的pub/sub模式用法

作为一个MQ,pub/sub是非常常见的一个用法,nanomsg作为ZMQ的继任,很少有博客讲述nanomsg的订阅/发布模式。


官方DEMO

#include <assert.h>
#include <libc.h>
#include <stdio.h>
#include <nanomsg/nn.h>
#include <nanomsg/pubsub.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)
    {
      char *d = date();
      int sz_d = strlen(d) + 1; // '\0' too
      printf ("SERVER: PUBLISHING DATE %s\n", d);
      int bytes = nn_send (sock, d, sz_d, 0);
      assert (bytes == sz_d);
      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);
  // TODO learn more about publishing/subscribe keys
  assert (nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, "", 0) >= 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;
    }
}

我以官方DEMO来说明如何使用订阅发布

订阅相关

assert (nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, topic, length(topic)) >= 0);

说明:

    这里推荐的TOPIC 类型是字符串类型。一次订阅只能订阅一个TOPIC。

    如果你想订阅两个TOPIC,如"SHANGHAI", "BEIJING",订阅两次。

assert (nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, "SHANGHAI", strlen(SHANGHAI)) >= 0);
assert (nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, "BEIJING", strlen(BEIJING)) >= 0);

发布相关

如何发布一个内容?

int bytes = nn_send (sock, d, content, length(content));
上述伪代码说明如下

content是你想发布的内容。

length(content)是发布的内容的长度

如发布上海的天气

int bytes = nn_send (sock, d, "SHANGHAI|20'-25',SUN", strlen("SHANGHAI|20'-25',SUN");

上面发布的内容接收方接收的数据的形式?

只有订阅了

SHANGHAI***的订阅方才能受到数据,我没阅读源码,估计发布的内容会遍历订阅的话题,通配开头内容相匹配的话题。---这样的做法性能应该是不会很高的,但是可以适应多种订阅业务的数据类型。

我感觉以字符串做TOPIC,构建显式的发布接口,以如下形式提供更合理

pub(topic, content)

接收方以实现。

OnSub(topic, content)

这样的方式可以用HASHMAP来管理TOPIC。


综述

NANOMSG的订阅发布不是很高级。或者说,不是纯粹的订阅发布业务类型。至少,没有强制化树立订阅主题。每次发布主题,需要遍历通配所有的订阅主题(性能有待提高)。

如果需要这样强类型的主题,可以考虑ZMQ,需要注意的是,ZMQ的FILTER是在SUB端处理的,意味着所有的MSG都会推给所有的Suber方(非常欠缺),或者有空可以考虑自己实现一个。


参考链接

http://nanomsg.org/v0.5/nn_pubsub.7.html

http://tim.dysinger.net/posts/2013-09-16-getting-started-with-nanomsg.html

https://github.com/nanomsg/nanomsg

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值