概述:
这次是nanomsg库实现的一个类似于MQTT通信的一种方式,广播订阅的一个一对多的通信方式。一个主的广播消息,其他可以订阅自己想要的主题信息,然后就会只接收订阅的主题的信息。
PubSub一对多主题订阅通信Demo
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <nanomsg/pubsub.h>
#include <nanomsg/nn.h>
/*
此程序为nanomsg多线程一对多单向通信demo,类似MQTT通信,一个广播,其他为订阅相应主题
客户端只接收到自己订阅的对应主题的内容。
*/
//inproc 标识用于多线程通信
char *url = "inproc://sky_test";
//发送数据的socket初始化
int send_sock_init(int *sock)
{
*sock = nn_socket (AF_SP, NN_PUB);
if (*sock < 0) {
printf("create send data sock failed\r\n");
return 1;
}
if (nn_bind(*sock, url) < 0) {
printf("bind send data sock failed\r\n");
return 1;
}
printf("send data socket init success...\r\n");
return 0;
}
//接收数据的socket初始化
int recieve_sock_init(int *sock, char *topic)
{
*sock = nn_socket (AF_SP, NN_SUB);
if (*sock < 0) {
printf("create recieve data sock failed\r\n");
return 1;
}
if (NULL == topic) {
//设置订阅主题为全部
nn_setsockopt(*sock, NN_SUB, NN_SUB_SUBSCRIBE, "", 0);
} else {
//设置订阅的主题及主题长度,主要是对比发送内容的开始字节
//如设置主题为"sky:",那么就会对比信息前面字节是否相同,相同则可以收到该信息
nn_setsockopt(*sock, NN_SUB, NN_SUB_SUBSCRIBE, topic, strlen(topic));
}
if (nn_connect(*sock, url) < 0) {
printf("connect recieve data sock failed\r\n");
return 1;
}
printf("recieve data socket init success...\r\n");
return 0;
}
//线程1测试
void *thread_test(void *arg)
{
int c_sock;
if (0 != recieve_sock_init(&c_sock, "sky:")) {
return;
}
while (1) {
//轮询接收订阅主题"sky:"信息
char *rx_msg = NULL;
int result = nn_recv(c_sock, &rx_msg, NN_MSG, NN_DONTWAIT);
if (result > 0) {
printf("Thread 1 Recieve: %s\r\n\r\n", rx_msg);
nn_freemsg (rx_msg);
}
sleep(1);
}
}
//线程2测试
void *thread_test2(void *arg)
{
int c_sock;
if (0 != recieve_sock_init(&c_sock, "born:")) {
return;
}
while (1) {
//轮询接收订阅主题"born:"信息
char *rx_msg = NULL;
int result = nn_recv(c_sock, &rx_msg, NN_MSG, NN_DONTWAIT);
if (result > 0) {
printf("Thread 2 Recieve: %s\r\n\r\n", rx_msg);
nn_freemsg (rx_msg);
}
sleep(1);
}
}
//发送数据
int send_data(int sock, char *data)
{
if (data == NULL) {
return 1;
}
if (nn_send(sock, data, strlen(data)+1, 0) < 0) {
return 1;
}
printf("Main Server Send:%s\r\n\r\n", data);
return 0;
}
int main()
{
int s_sock, ret, i = 0;
pthread_t ps, ps2;
char *tx_msg = "sky:Hello Thread Sky";
char *tx_msg1 = "born:Hello Thread Born";
char *tx_msg2 = "Storm:Hello Thread Storm";
if (0 != send_sock_init(&s_sock)) {
return 1;
}
//创建子线程,接收信息
pthread_create(&ps, NULL, thread_test, NULL);
pthread_create(&ps2, NULL, thread_test2, NULL);
sleep(1);
//间隔两秒,发送信息到子线程接收数据端
while (1) {
//测试发送广播
if (0 == i) {
ret = send_data(s_sock, tx_msg);
if (0 == ret) {
i ++;
}
} else if (1 == i) {
ret = send_data(s_sock, tx_msg1);
if (0 == ret) {
i ++;
}
} else if (2 == i) {
ret = send_data(s_sock, tx_msg2);
if (0 == ret) {
i = 0;
}
}
sleep(2);
}
return 0;
}
编译
gcc -o nanomsg_pubsub nanomsg_pubsub.c -lnanomsg -lpthread
运行结果:
sky@ubuntu:~/Study/nanomsg/code_test/inproc/pubsub$ ./nanomsg_pubsub
send data socket init success...
recieve data socket init success...
recieve data socket init success...
Main Server Send:sky:Hello Thread Sky
Thread 1 Recieve: sky:Hello Thread Sky
Main Server Send:born:Hello Thread Born
Thread 2 Recieve: born:Hello Thread Born
Main Server Send:Storm:Hello Thread Storm
Main Server Send:sky:Hello Thread Sky
Thread 1 Recieve: sky:Hello Thread Sky
...
根据结果可以看到,线程1,2分别订阅了sky born主题,所以可以收到,而storm主题没订阅所以都没有收到。