1.前言
今天使用了下.NET平台的消息队列NetMQ,在这里记录下.博客园张善友也有较好的例子,只不过我这个例子在张兄的基础上稍微扩展了下.张兄的NetMQ介绍文章只是从客户端向服务端发送字符串,服务端收到后返回一个消息,我这里设想发送委托及参数到服务端执行,服务端返回执行状态.
2.下载NetMQ
Install-Package NetMQ
3.Demo
1)客户端
using NetMQ;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using NetMQ.Common;
namespace NetMQClient
{
class Program
{
static void Main(string[] args)
{
using (NetMQContext context = NetMQContext.Create())
{
Client(context);
}
Console.ReadKey();
}
static void Client(NetMQContext context)
{
using (NetMQSocket clientSocket = context.CreateRequestSocket())
{
clientSocket.Connect("tcp://127.0.0.1:5555");
Dictionary<string,object> dic = new Dictionary<string,object>();
dic.Add("a",1);
dic.Add("b",2);
Message msg = new Message()
{
Id = 0,
FunName = "Calc",
Params = dic,
Result = ""
};
byte[] buffer = ByteConvertHelper.Object2Bytes(msg);
clientSocket.SendFrame(buffer);
string answer = clientSocket.ReceiveFrameString();
Console.WriteLine("Answer from server: {0}", answer);
}
}
}
}
2)服务端
using NetMQ;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using NetMQ.Common;
namespace NetMQDemo
{
class Program
{
static void Main(string[] args)
{
using (NetMQContext context = NetMQContext.Create())
{
Server(context);
}
Console.ReadKey();
}
static int Calc(int a, int b)
{
return a + b;
}
static void Server(NetMQContext context)
{
using (NetMQSocket serverSocket = context.CreateResponseSocket())
{
serverSocket.Bind("tcp://127.0.0.1:5555");
byte[] buffer = serverSocket.ReceiveFrameBytes();
Message msg = (Message)ByteConvertHelper.Bytes2Object(buffer);
msg.Result = (Calc((int)msg.Params["a"],(int)msg.Params["b"]).ToString());
Console.WriteLine("Result:" + msg.Result);
serverSocket.SendFrame("Result:" + msg.Result);
}
}
}
}
3).Common
3.1)对象和字节数组互相转化的Helper
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace NetMQ.Common
{
public class ByteConvertHelper
{
/// <summary>
/// 将对象转换为byte数组
/// </summary>
/// <param name="obj">被转换对象</param>
/// <returns>转换后byte数组</returns>
public static byte[] Object2Bytes(object obj)
{
byte[] buff;
using (MemoryStream ms = new MemoryStream())
{
IFormatter iFormatter = new BinaryFormatter();
iFormatter.Serialize(ms, obj);
buff = ms.GetBuffer();
}
return buff;
}
/// <summary>
/// 将byte数组转换成对象
/// </summary>
/// <param name="buff">被转换byte数组</param>
/// <returns>转换完成后的对象</returns>
public static object Bytes2Object(byte[] buff)
{
object obj;
using (MemoryStream ms = new MemoryStream(buff))
{
IFormatter iFormatter = new BinaryFormatter();
obj = iFormatter.Deserialize(ms);
}
return obj;
}
}
}
3.2)消息实体
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NetMQ.Common
{
[Serializable]
public class Message
{
public int Id { set; get; }
public string FunName { set; get; }
public Dictionary<string, object> Params { set; get; }
public string Result { set; get; }
}
}
注意:必须加Serializable属性
4.结果
5.总结
NetMQ目前还不支持持久化消息,所以,可靠性不是特别高.消息队列基本的特性都满足,效率也很高.