C#使用NetMQ
NetMQ是我在网吧项目中所使用的一种消息队列,是ZeroMQ在.net平台上的移植版本,非常轻量级,使用方便,响应速度快,代码也便于阅读和编写,但是功能比较少,适合在小型项目中进行使用。
这次在项目中,需要对发往客户端的消息进行加密,然后客户端自行解密来确保发送的消息不会被别人看到,在这种情况下,很自然的想到了使用非对称加密算法来对消息进行加密(其实在之前有想过采用类似WCF中的身份认证方式来防止别人连接到这个接口,但是我翻阅了一下官方文档,NetMQ似乎并没有这个功能,所以最后采用了消息加密的功能,这个当然也是一个比较普遍的方式)。
使用NETMQ
NetMQ的使用还是非常方便的,在项目中直接引用netmq.dll就可以直接使用了,所以这里就不再赘述如何下载安装,直接进入正题:如何使用NetMQ。
属性和构造函数
public class ShowServer
{
private static ShowServer showServer = null;
private RouterSocket ServerSocket;
private NetMQPoller Poller;
private NetMQMonitor Monitor;
public Queue<MsgObject> SendMessageQueue;
public IProgress<MsgObject> ReceiveHanlder;
private IProgress<MsgObject> receiveHanlder;
private Queue<MsgObject> EventQueue;
public bool IsRunning {
get; set; }
/// <summary>
/// 构造函数
/// </summary>
private ShowServer()
{
SendMessageQueue = new Queue<MsgObject>();
EventQueue = new Queue<MsgObject>();
ServerSocket = new RouterSocket("tcp://0.0.0.0:6667");
ServerSocket.ReceiveReady += ServerSocket_ReceiveReady;
ServerSocket.SendReady += ServerSocket_SendReady;
ServerSocket.Options.RouterHandover = true;
Monitor = new NetMQ.Monitoring.NetMQMonitor(ServerSocket, "inproc://show.inproc", SocketEvents.All);
Monitor.Accepted += Monitor_Accepted;
Monitor.Disconnected += Monitor_Disconnected;
receiveHanlder = new Progress<MsgObject>(HandleMsg);
ReceiveHanlder = receiveHanlder;
Poller = new NetMQPoller() {
ServerSocket };
}
public static ShowServer GetServer()
{
if(showServer == null){
showServer = new ShowServer();
}
return showServer;
}
private void Monitor_Accepted(object sender, NetMQMonitorSocketEventArgs e)
{
System.Diagnostics.Debug.WriteLine(DateTime.Now + "连接上 ,address:" + e.Address);
}
private void Monitor_Disconnected(object sender, NetMQMonitorSocketEventArgs e)
{
System.Diagnostics.Debug.WriteLine(DateTime.Now + "" + e.Address);
}
private void ServerSocket_SendReady(object sender, NetMQSocketEventArgs e)
{
while (SendMessageQueue.Count > 0)
{
try
{
var sendMsg = SendMessageQueue.Dequeue();
if (sendMsg.Content == null)
{
continue;
}
var msgFrame = ConvertToNetMessage(sendMsg);
ServerSocket.SendMultipartMessage(msgFrame);
}
catch (Exception ex)
{
Log.WriteLog_EX(ex.ToString());
}
}
//发送数据间隔
Thread.Sleep(10);
}
private NetMQMessage ConvertToNetMessage(MsgObject sendMsg)
{
var msgFrame = new NetMQMessage();
msgFrame.Append(sendMsg.MachineName);
msgFrame.AppendEmptyFrame();
msgFrame.Append(sendMsg.Content, Encoding.UTF8);
return msgFrame;
}
private MsgObject ConvertToMsgObj(NetMQMessage sendMsg)
{
if (sendMsg.FrameCount == 3)
{
var newMsg = new MsgObject();
var machineName = sendMsg[0].ConvertToString();
//var content = sendMsg[2].ConvertToString();
var content = Encoding.UTF8.GetString(sendMsg[2].Buffer);
newMsg.MachineName = machineName;
newMsg.Content = content;
return newMsg;
}
return null;
}
private void ServerSocket_ReceiveReady(object sender, NetMQSocketEventArgs e)
{
var msg = ConvertToMsgObj(ServerSocket.ReceiveMultipartMessage());