使用ZeroMQ(clrzmq)实现异步通信
ZeroMQ是对Socket的封装,通过组合多种类型的结点可以实现复杂的网络通信模式。而且ZeroMQ设计简单,可以有多种平台实现,对于跨平台项目是一个福音。
clrzmq是ZeroMQ的C#语言的实现。当我在使用clrzmq时,发现ZeroMQ的server端,即REP,在接收到消息后,回复消息,但是在回复消息之前不能再接收消息。用伪代码表示就是
while(true)
{
byte[] receiveData = new byte[];
receive(receiveData); //do some work
byte[] responseData = new byte[];
send(reponseData);
}
既然ZeroMQ的名称里含有MQ(Message Queue),就应该有队列的功能啊?在ZeroMQ的官方手册中介绍了router-dealer模式:
router可以作为路由器,起到缓存消息的作用,如果服务端空闲,会把消息通过dealer发送给服务端。
这篇文章使用C++实现了ZeroMQ消息队列。
幸运的是,clrzmq对router-dealer模式进行了封装,可以使用QueueDevice类实现相同的效果。
在我的例子中,我将router-dealer放在了服务端进程中,dealer和服务端的通信是县城通信,交互图如下:
static void Main(string[] args)
{
string serverAddress = "tcp://localhost:5555";
// ZMQ Context and client socket
using (ZmqContext context = ZmqContext.Create())
using (ZmqSocket client = context.CreateSocket(SocketType.REQ))
{
client.Connect(serverAddress); string request = "Hello";
while(true)//for (int requestNum = 0; requestNum < 10; requestNum++)
{
string again = Console.ReadLine(); Console.WriteLine("Sending request...");
client.Send(again + request, Encoding.Unicode); string reply = client.Receive(Encoding.Unicode);
Console.WriteLine("Received reply {0}: ", reply);
} }
}
class Program
{
static ZmqContext context = ZmqContext.Create();
static ManualResetEvent _deviceReady = new ManualResetEvent(false);
//static ManualResetEvent _receiverReady = new ManualResetEvent(false); static void Main(string[] args)
{
startRouterDealer();
// ZMQ Context, server socket
_deviceReady.WaitOne(); using (ZmqSocket server = context.CreateSocket(SocketType.REP))
{
//server.Bind("inproc://backend");
server.Connect("inproc://backend"); while (true)
{ // Wait for next request from client
string message = server.Receive(Encoding.Unicode);
Console.WriteLine("Received request: {0}", message); //ThreadPool.QueueUserWorkItem(new WaitCallback(procedeRequest), server);
// Do Some 'work'
Thread.Sleep(); // Send reply back to client
server.Send(message, Encoding.Unicode);
}
}
} private static void startRouterDealer()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(startQueueDeviceThread), null);
//ThreadPool.QueueUserWorkItem(new WaitCallback(startRouterDealerThread), null);
}
private static void startQueueDeviceThread(object state)
{
//Thread.Sleep(2000);
using (QueueDevice queue = new QueueDevice(context,
"tcp://*:5555",
"inproc://backend",
DeviceMode.Threaded))
{
queue.Initialize();
_deviceReady.Set();
queue.Start();
while(true)
{
Thread.Sleep();
}
}
}
}
ZeroMQ的手册中介绍说,router-dealer必须先启动,服务端再启动,因此ManualResetEvent 的作用是协调QueueDevice和服务端的启动顺序。
使用ZeroMQ(clrzmq)实现异步通信的更多相关文章
- PHP Log时时查看小工具
以前Log都是打印在一个文档中,然后打开文件夹,最后打开文档查看里面的内容,每次打开文件夹感觉很烦. 前些日子看到同事开发.NET的时候,用他自己的一个小工具能够时时查看到Log的内容,非常方便,所以 ...
- 0mq 入门 (转)
最近做后台发现很多地方需要队列,我用东西一般有两个要求: 1) 够傻够简单. 2) 有源码,能看又能改. 最后相中了0mq,下面介绍如何安装和写个简单的例子.一. linux平台: ...
- 消息通信库ZeroMQ 4.0.4安装指南
一.ZeroMQ介绍 ZeroMQ是一个开源的消息队列系统,按照官方的定义,它是一个消息通信库,帮助开发者设计分布式和并行的应用程序. 首先,我们需要明白,ZeroMQ不是传统的消息队列系统(比如Ac ...
- ZeroMQ安装
一.ZeroMQ介绍 ZeroMQ是一个开源的消息队列系统,按照官方的定义,它是一个消息通信库,帮助开发者设计分布式和并行的应用程序. 首先,我们需要明白,ZeroMQ不是传统的消息队列系统(比如Ac ...
- ZeroMQ 在 centos 6.5_x86_64 下的安装
ZeroMQ 在 centos 6.5_x86_64 下的安装 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 一.ZeroMQ介绍 ZeroMQ是一个开 ...
- WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(三)实现ReplyChannel(2016-03-15 12:35)
这是这个系列的第三篇,其他的文章请点击下列目录 WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(一)概要设计 WCF扩展之实现ZeroMQ绑定和protocolBuffer消息 ...
- rabbitMQ、activeMQ、zeroMQ、Kafka、Redis 比较
Kafka作为时下最流行的开源消息系统,被广泛地应用在数据缓冲.异步通信.汇集日志.系统解耦等方面.相比较于RocketMQ等其他常见消息系统,Kafka在保障了大部分功能特性的同时,还提供了超一流的 ...
- 【Linux】ZeroMQ 在 centos下的安装
转自:http://www.cnblogs.com/mjorcen/p/4479642.html 一.ZeroMQ介绍 ZeroMQ是一个开源的消息队列系统,按照官方的定义,它是一个消息通信库,帮助开 ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
随机推荐
- Android中网络流量控制(防火墙)——Iptables
Iptables简单介绍 iptables是与最新的 2.6.x 版本号 Linux 内核集成的 IP 信息包过滤系统. 假设 Linux 系统连接到因特网或 LAN.server或连接 LAN 和因 ...
- git版本号回滚
先说今天遇到的问题,看到一个config.php的配置文件一直在改动的状态下,可是和远程的config.php是不一致的,我不须要提交它,可是看它在 modified的状态下,非常不爽.想删除它.gi ...
- iOS:点击button卡死
场景: 在tableView的Cell中有一个button,我须要点击这个button然后使得其视图控制器上的一个视图改变frame,可是我点击这个button后,导致卡死,也不崩溃.所有事 ...
- [Cocos2d-x]节点之间的相互通讯
在做.NET开发时,对象之间的相互通讯一般使用事件(event)实现,事件概念是.NET对Delegate的封装. 在Cocos2d-x开发过程中,对象之间的通讯刚开始时不知道如何实现,于是想到c++ ...
- Java发展的时间表
Java发展的时间表. (版本号 名称 中文名 发布日期) JDK 1.1.4 Sparkler 宝石 1997-09-12 JDK 1.1.5 Pumpkin 南瓜 1997-12-13 JDK 1 ...
- hdu1876(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1876 题意:问机器人到达终点的过程中最多有几次完全消耗完能量,消耗完这么多次能量的方式有几种. 分析: ...
- 2014年辛星解读Javascript之用DOM动态操纵HTML元�
关于DOM,我们了解了能够用DOM操纵HTML的一些属性和样式,还能够为HTML元素绑定事件等等,那么接下来,我们将涉及到用DOM来动态的创建.删除HTML等一些操作,我的核心思路还是重实战,因此,代 ...
- 【cocos2d-x不要在生产白片步骤】第二项:制作Block分类
由于游戏非常多使用阻断,因此,我们创建了一个单独的类中Block. 于Blcok.h声明了两个初始化函数: static Block* createWithArgs(Color3B color, Si ...
- RequireJS和JQuery的模块化编程
基于RequireJS和JQuery的模块化编程 由于js的代码逻辑越来越重,一个js文件可能会有上千行,十分不利于开发与维护.最近正在把逻辑很重的js拆分成模块,在一顿纠结是使用requirejs还 ...
- Effective C++ 条款24
若全部參数皆需类型转换,请为此採用non-member函数 我们直奔主题 假设你定义一个有理数类例如以下 class Rational{ public: Rational(int numerator= ...