转载自本人博客:https://www.jjy2023.cn/2024/06/27/%e4%b8%80%e6%96%87%e5%85%a5%e9%97%a8nanomsg%e9%80%9a%e4%bf%a1%e5%ba%93/

1. Nanomsg介绍
Nanomsg官方在线文档:https://nanomsg.org/index.html
本文全部代码用C++实现。
以前一直在使用ZeroMQ库处理通信,但因为最近需要做一个一对多的双向实时通信,ZeroMQ提供的几种通信模式就难以很好地实现,于是就去寻找其他的库,比如Nanomsg库。
若想了解ZeroMQ和NanoMSG的区别,想要知道如何选择,可以看看我另一篇小文章:ZeroMQ和NanoMSG的选择/对比
按照官方的说明,NanoMsg相当于ZeroMQ的改进升级版。Nanomsg库提供多种常见通信模式,它旨在使网络层快速、可扩展且易于使用。它以C语言实现,适用于广泛的操作系统,没有进一步的依赖关系。
2. Nanomsg通信模式详解
Nanomsg提供了六种可扩展协议,是在网络通信协议上实现的,我觉得理解成通信模式更好。
- PAIR :简单的一对一通信
- BUS:简单的多对多通信
- REQREP :允许构建无状态集群来处理用户请求
- PIPELINE :汇总来自多个来源的消息,并在许多目的点之间进行负载平衡
- PUBSUB :将消息分发给订阅消息的用户
- SURVEY :允许一次查询多个应用程序的状态
2.1 PAIR(配对)模式

在两个节点间实现简单的一对一双向通信,允许两个节点互相发送消息让对方接收,对发送、接收都没有限制。
代码实现:
//节点0
#include <nanomsg/nn.h>
#include <nanomsg/pair.h> //注意PAIR头文件
if((node0 = nn_socket(AF_SP, NN_PAIR)) < 0){ // 新建soocket,选择PAIR模式
cout << "socket creat error";
}
if(nn_bind(node0, "tcp://127.0.0.1:5555") < 0){ // 绑定地址,用返回值判断结果
cout << "connect error";
}
string sendMsg = "node0";
if(nn_send(node0, sendMsg, sendMsg.size(), 0) < 0){
cout << "send error";
}
...
// 多开一个线程可用于同时接收数据
string *recvMsg;
while(true){
nn_recv(node0, &recvMsg, NN_MSG, 0);
}
...
//节点1
#include <nanomsg/nn.h>
#include <nanomsg/pair.h> //注意PAIR头文件
if((node1 = nn_socket(AF_SP, NN_PAIR)) < 0){ // 新建soocket,选择PAIR模式
cout << "socket creat error";
}
if(nn_connect(node1, "tcp://127.0.0.1:5555") < 0){ // 建立连接
cout << "connect error" ;
};
string *recvMsg;
while(true){
nn_recv(node1, &recvMsg, NN_MSG, 0);
}
... // 多开一个线程可用于随时发送数据
string sendMsg = "node1";
if(nn_send(node1, sendMsg, sendMsg.size(), 0) < 0){
cout << "send error";
}
...
2.2 BUS(总线)模式

此模式是Nanomsg相对于ZeroMQ新增的一个通信模式,所有绑定到一个地址的节点共用一个总线,发送数据都是推送到总线,接收数据也是从总线拉取数据。即某一个节点发送的数据可以被其他节点都收到,同时,这个节点也可以接收到其他节点发送的任意数据。
相比于上面官方的拓扑图,用下图来表示更为贴切:

代码实现:
//节点0
#include <nanomsg/nn.h>
#include <nanomsg/bus.h> //注意BUS头文件
if((node0 = nn_socket(AF_SP, NN_BUS)) < 0){ // 新建soocket,选择BUS模式
cout << "socket creat error";
}
if(nn_bind(node0, "tcp://127.0.0.1:5555") < 0){ // 绑定地址,用返回值判断结果
cout << "connect error";
}
string sendMsg = "hello";
if(nn_send(node0, sendMsg, sendMsg.size(), 0) < 0){ // 发送数据,用返回值判断结果
cout << "send error";
}
...
// 多开一个线程可用于同时接收数据
// 不用connect也能接收,当然也可以connect
string *recvMsg;
while(true){
nn_recv(node0, &recvMsg, NN_MSG, 0);
}
...
//节点1
#include <nanomsg/nn.h>
#include <nanomsg/bus.h> //注意BUS头文件
if((node1 = nn_socket(AF_SP, N

1万+

被折叠的 条评论
为什么被折叠?



