C# 使用 RabbitMQ
1. RabbitMQ
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。其中较为成熟的MQ产品有MSMQ,ActiveMQ,RabbitMQ,IBM WEBSPHERE MQ 等。
RabbitMQ是使用Erlang开发的,开源的,一个在高级消息队列协议(AMQP)基础上完整的,可复用的企业消息系统,遵循Mozilla Public License开源协议。
RabbitMQ支持大多数开发语言如Java,Ruby,Python,.Net,C/C++,Erlang等,各种语言的客户端可以从官网上下载。
2. RabbitMQ的一些概念
- 连接(Connection),与RabbitMQ Server建立的一个连接,由ConnectionFactory创建,每个connection只与一个物理的Server进行连接,此连接是基于Socket进行连接的,这个可以相似的理解为像一个DB Connection。AMQP一般使用TCP链接来保证消息传输的可靠性。
- 通道 (Channel),在C#客户端里应该是叫Model,其他客户端基本都叫Channel。建立在Connection基础上的一个通道,相对于Connection来说,它是轻量级的。它就像是Hibernate里面的Session一样。Channel 主要进行相关定义,发送消息,获取消息,事务处理等。Channel可以在多线程中使用,但是必须保证任何时候只有一个线程执行命令。一个Connection可以有多个Channel。客户端程序有时候会是一个多线程程序,每一个线程都想要和RabbitMQ进行连接,但是又不想共享一个连接,这种需求还是比较普遍的。因为一个Connection就是一个TCP链接,RabbitMQ在设计的时候不希望与每一个客户端保持多个TCP连接,但这确实是有些客户端的需求,所以在设计中引入了Channel的概念,每一个Channel之间没有任何联系,是完全分离的。多个Channel来共享一个Connection。
- 交换器(Exchange),发送消息的实体。
- 队列(Queue),接收消息的实体。
- 绑定器(Bind),将交换器和队列连接起来,并且封装消息的路由信息。
3.资源文件
4.发送消息
1 /// <summary> 2 /// </summary> 3 /// <param name="deptId">部门id</param> 4 /// <param name="userCode">用户名</param> 5 /// <returns></returns> 6 [Generated] 7 protected override String SendMQ(long deptId, string userCode, string clientIP) 8 { 9 var factory = new ConnectionFactory(); 10 factory.HostName = "182.94.73.104"; //MQ服务端IP 11 factory.Port = 15673; //MQ 服务端端口 12 factory.UserName = "login_mq_user"; 13 factory.Password = "chinaiss_xyz@345Q1uTfcx.vb"; 14 //factory.HostName = "localhost"; 15 //factory.UserName = "yy"; 16 //factory.Password = "hello!"; 17 18 19 string ticket = System.Guid.NewGuid().ToString(); //对应URL中的token参数 20 21 //MQINFOPoco MQobj = new MQINFOPoco(); 22 //MQobj.clientIP = clientIP; 23 //MQobj.section = deptId; 24 //MQobj.userId = userCode; 25 //MQobj.loginTime = GetTimeStamp(); 26 //MQobj.timeLive = 480; 27 //MQobj.token = ticket; 28 var loginTime = GetTimeStamp(); 29 30 using (var connection = factory.CreateConnection()) 31 { 32 using (var channel = connection.CreateModel()) 33 { 34 channel.QueueDeclare("login_queue", false, false, false, null); //MQ队列名称login_queue 35 //string message = ObjectToJson(MQobj); 36 StringBuilder message = new StringBuilder(@"{""clientIP"":"); 37 message.AppendFormat("\"{0}\"", clientIP); 38 message.AppendFormat(",\"section\":\"{0}\"", deptId); 39 message.AppendFormat(",\"userId\":\"{0}\"", userCode); 40 //message.Append(",\"userId\":\"hxj\""); 41 message.AppendFormat(",\"loginTime\":{0}", loginTime); 42 message.Append(",\"timeLive\":480"); 43 message.AppendFormat(",\"token\":\"{0}\"", ticket); 44 message.Append("}"); 45 46 var properties = channel.CreateBasicProperties(); 47 properties.SetPersistent(true); 48 var body = Encoding.UTF8.GetBytes(message.ToString()); 49 channel.BasicPublish("", "login_queue", properties, body); 50 } 51 } 52 53 return ticket; 54 }