rabbitmq 消费端代码获取队列名称_C#调用RabbitMQ实现消息队列的示例代码

前言

我在刚接触使用中间件的时候,发现,中间件的使用并不是最难的,反而是中间件的下载,安装,配置才是最难的。

所以,这篇文章我们从头开始学习RabbitMq,真正的从头开始。

关于消息队列

其实消息队列没有那么神秘,我们这样想一下,用户访问网站,最终是要将数据以HTTP的协议的方式,通过网络传输到主机的某个端口上的。

那么,接收数据的方式是什么呢?自然是端口监听啦。

那消息队列是什么就很好解释了?

它就是端口监听,接到数据后,将数据排列起来。

那这件事,我们不用中间件能做吗?

当然能做啦,写个TCP/UDP/Socket的软件就可以做啦。

举个简单的例子,如下图:

既然自己可以做消息队列,那为什么要用RabbitMQ?

因为,RabbitMQ成熟的开源中间件,可靠性有保证,bug少,性能也非常好。

而C#代码默认是使用托管内存的,所以,想写出媲美RabbitMQ性能的消息队列,就必须离开我们常用的托管内存,使用非托管内存,但这个代价就太大了;而且最终能否达到RabbitMQ的性能水平还是个未知数。

还有就是RabbitMQ除了基础的消息队列管理,还有很多很强大的额外功能,而自己开发消息队列,很难如此尽善尽美。

我们还会发现,在消息队列里有很多概念,什么消息总线啊,什么工作队列啊等等。

要怎么理解这些概念呢?

很简单,不要去理解。这些概念其实是人家代码架构的模式,不要去理解他们,【记】就完了,人家的中间件就是按照这个模式工作的。

比如,我写了一个接收消息的总控制器,然后我为他命名为总线,那这个控制器就是总线,没有理由,这就是定义。

准备工作

首先,我们访问官网【https://www.rabbitmq.com/】,点击Get Started。

然后,网站会自动跳转到当前首页Get Started的锚点位置,如下图:

Get Started锚点:

然后我们点击DownLoad+Installation,进入到下载界面。

在下载页面中,我们找到安装指南,然后在点击官网推荐的Windows系统的安装包,如下图:

现在,我们进入了Windows安装指南界面了。

首先,我们看一下预览信息,如下图:

在预览里,我们得知,安装RabbitMQ有两种方法,一种是使用Chocolatey安装,一种是使用官方安装包安装。

Chocolatey是什么呢?随手百度一下,原来他是一个软件包管理工具,也就是说,Chocolatey是类似于Nuget的一种工具。

由于Chocolatey的使用,我不是很熟悉,所以,这里选择使用官方安装包安装。

点击【Using the official installer】,我们进入了【Using the official installer】对应的锚点,如下图。

在【Using the official installer】段落里找到有推荐标志的安装包,然后下载。

下载完成后,我们可以得到这样一个安装包,如下图:

除了下载安装包,我们还会发现,在【Using the official installer】段落里,有提醒我们,RabbitMQ是有依赖的,依赖一个Erlang语言的框架(类似于C#语言的NetFramework)。

我们可以发现,在依赖的段落里,官网非常坑的给出了三个链接网址,如下:

因为,我们是无法通过文字描述来判断,哪一个是真的依赖框架的下载地址,所以只好每个都点击进去看看。。。

打开网址后发现,在后两个网址中都可以找到框架下载地址,但第二个地址明显更友好一点,所以我们在第二个网址内下载Erlang的框架。

下载完成得到如下图文件:

PS:这里下载的是OTP的22.1的版本,我的理解是Erlang等于C#语言,而OTP等于NetFramework。

安装Erlang\OTP

首先,我们运行otp_win64_22.1.exe,安装依赖框架Erlang\OTP。

安装完成后,设置环境变量如下:

然后运行CMD,输入erl,测试安装是否成功,如下图:

安装成功。

安装rabbitmq-server

安装完依赖后,我们接着安装rabbitmq-server-3.8.0.exe。

【rabbitmq-server-3.8.0.exe】?从这个文件名上,我们发现了一个问题,那就是,我们即将安装的RabbitMQ,是一个服务端啊。

什么?服务端?难道还有客户端???

其实这也很好理解,想一下最开始我举的那个例子,消息队列是需要一个监听端口的服务端的,然后客户端向这个服务端发送请求。

这样是不是就很好的理解RabbitMQ了呢:)

安装完RabbitMQ服务端后,我们还是启动CMD,用命令行来查看下安装状态。

首先输入下面的命令,将路径定位到RabbitMQ的路径下:

【CD /D C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.0\sbin】

然后输入rabbitmqctl status查看状态。

启动管理工具的命令行:rabbitmq-plugins enable rabbitmq_management。

启动成功后,在浏览器输入地址http://127.0.0.1:15672/,进入管理页面,账户密码都是guest。

RabbitMQ还有很多常用命令,大家可以自行百度。

到此,RabbitMQ服务端的环境配置好了,正常情况,这些配置应该在服务器进行,但我为了测试方便,就把服务端也安装在本机了,因此我下面调用RabbitMQ时,连接的主机IP都是localhost。

RabbitMQ应用

首先创建两个控制台应用程序,KibaRabbitMQSend和KibaRabbitMQReceived。

然后引入RabbitMQ的开源类库。

在C#里使用RabbitMQ开源类库非常简单,可以去官网下载一个.NET版本的RabbitMQ客户端类库,也可以直接在Nuget上搜索RabbitMQ,然后安装,如下图:

KibaRabbitMQSend

安装完RabbitMQ开源类库后,我们编写代码,实现向RabbitMQ服务器发送消息,代码如下:

static void Main(string[] args)

{

var factory = new ConnectionFactory();

factory.HostName = "localhost";//主机名,Rabbit会拿这个IP生成一个endpoint,这个很熟悉吧,就是socket绑定的那个终结点。

factory.UserName = "guest";//默认用户名,用户可以在服务端自定义创建,有相关命令行

factory.Password = "guest";//默认密码

using (var connection = factory.CreateConnection())//连接服务器,即正在创建终结点。

{

//创建一个通道,这个就是Rabbit自己定义的规则了,如果自己写消息队列,这个就可以开脑洞设计了

//这里Rabbit的玩法就是一个通道channel下包含多个队列Queue

using (var channel = connection.CreateModel())

{

channel.QueueDeclare("kibaQueue", false, false, false, null);//创建一个名称为kibaqueue的消息队列

var properties = channel.CreateBasicProperties();

properties.DeliveryMode = 1;

string message = "I am Kiba518"; //传递的消息内容

channel.BasicPublish("", "kibaQueue", properties, Encoding.UTF8.GetBytes(message)); //生产消息

Console.WriteLine($"Send:{message}");

}

}

}

运行代码。

然后我们使用命令行rabbitmqctl list_queues,去RabbitMQ的服务器查看当前消息队列,如下图:

可以看到,我们的消息已经发送成功了。

KibaRabbitMQReceived

现在我们编写接收消息代码,如下:

static void Main(string[] args)

{

var factory = new ConnectionFactory();

factory.HostName = "localhost";

factory.UserName = "guest";

factory.Password = "guest";

using (var connection = factory.CreateConnection())

{

using (var channel = connection.CreateModel())

{

channel.QueueDeclare("kibaQueue", false, false, false, null);

/* 这里定义了一个消费者,用于消费服务器接受的消息

* C#开发需要注意下这里,在一些非面向对象和面向对象比较差的语言中,是非常重视这种设计模式的。

* 比如RabbitMQ使用了生产者与消费者模式,然后很多相关的使用文章都在拿这个生产者和消费者来表述。

* 但是,在C#里,生产者与消费者对我们而言,根本算不上一种设计模式,他就是一种最基础的代码编写规则。

* 所以,大家不要复杂的名词吓到,其实,并没那么复杂。

* 这里,其实就是定义一个EventingBasicConsumer类型的对象,然后该对象有个Received事件,

* 该事件会在服务接收到数据时触发。

*/

var consumer = new EventingBasicConsumer(channel);//消费者

channel.BasicConsume("kibaQueue", true, consumer);//消费消息

consumer.Received += (model, ea) =>

{

var body = ea.Body;

var message = Encoding.UTF8.GetString(body);

};

}

}

}

运行代码。

然后我们使用命令行rabbitmqctl list_queues,去RabbitMQ的服务器查看当前消息队列,如下图:

可以看到,消息已经被使用了。

现在我们在发送代码出做一个for循环,看看消息接收速度是什么样的,代码如下,for循环了100次,每次间隔3秒。

for (int i = 0; i < 100; i++)

{

channel.QueueDeclare("kibaQueue", false, false, false, null);//创建一个名称为kibaQueue的消息队列

var properties = channel.CreateBasicProperties();

properties.DeliveryMode = 1;

string message = "I am Kiba518"; //传递的消息内容

channel.BasicPublish("", "kibaQueue", properties, Encoding.UTF8.GetBytes(message)); //生产消息

Console.WriteLine($"Send:{message}");

Thread.Sleep(3000);

}

效果图如下:

可以看到,发送消息和接收消息,几乎是同步的,效果非常理想。

服务器端应用

在上文,我们的RabbitMQ服务是安装在我的本机上的;现在我们把服务移植到服务器上,然后再来测试一下。

在服务器端安装RabbitMQ和在本机安装的步骤是一样的,但是安装完成后,我们需要设置下防火墙的入站规则和出站规则,将5672的UDP端口开放一下。

为什么要开放端口是5672?因为RabbitMQ的默认的消息接收和发送端口就是5672,我们可以使用断点查看一下。

如上图,可以看到,在我们没有设置端口的时候,Endpoint的端口的默认值是5672。

配置完端口后,我们修改代码中的HostName为我们的服务器地址,如下。

factory.HostName = "1.1.1.1";

重新运行代码,会发现在运行到factory.CreateConnection()的时候,系统提示一个异常【RabbitMQ.Client.Exceptions.BrokerUnreachableException:“None of the specified endpoints were reachable”】,如下图:

这是因为我们使用的账号是guest,guest账号默认是不支持远程连接的。

解决办法很简单,新建一个账户即可。

创建用户

在服务器端打开浏览器,输入http://127.0.0.1:15672/,进入管理页面。

点击菜单栏的Admin选项,进入用户管理界面创建用户kiba,密码123456,如下图:

创建完用户后,得到如下界面。

如上图所示,刚刚创建的用户还没有任何访问权限。

现在我们点击用户名,进入权限管理页面设置权限。

如上图所示,页面默认为我们设置了一个可读,可写,可管理配置的权限;所以,我们只要点击Setpremission就可以了。

设置完权限,我们回到用户管理页面。

如上图所示,权限设置成功。

现在我们回到代码,修改用户名密码如下。

factory.HostName = "1.1.1.1";

factory.UserName = "kiba";

factory.Password = "123456";

运行代码,不再抛异常,接受发送消息正常。

设置用户权限也可以通过命令的方式设置,如下:

rabbitmqctl set_permissions -p "/" kiba "." "." ".*"

到此C#调用RabbitMQ实现消息队列就讲完了。

代码已经传到Github上了,欢迎大家下载。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433783.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python画饼图程序_python使用matplotlib画饼状图

本文实例为大家分享了python使用matplotlib画饼状图的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 代码与详细注释 from matplotlib import pyplot as plt #调节图形大小&#xff0c;宽&#xff0c;高 plt.figure(figsize(6,9)) #定义饼状图的标签&#xff0c;标签…

我的世界服务器显示英文,我的世界pixelmon服务器技能显示英文

满意答案zihezimu2019.04.21采纳率&#xff1a;43% 等级&#xff1a;13已帮助&#xff1a;4603人解决神奇宝贝服务器在精灵对战中技能显示为英文&#xff0c;并且对战后名字显示为英文的问题心得 联机教程 1282 浏览1 评论殒天 Lv.7 猎手2017-2-18 09:49:51很多神奇宝贝服务…

AM335X 分配大于4M的framebuffer

最近正在将800X480的设备修改成1024X600&#xff0c;算了一下&#xff0c; 1024X600X4X2需要4M的framebuffer空间&#xff0c;其中4代表一个像素32位色的Byte数&#xff0c; 2代表双framebuffer&#xff0c;LCD驱动程序中&#xff0c;使用dma_alloc_coherent来分配缓冲区 dm…

万年历升级版 Calendar

package com.yc.wnl;import java.util.Calendar; import java.util.Date; import java.util.Scanner;import com.yc.ycutil.DateUtil; //用于输出用户要求的年月对应的表格 public class CalendarTest {public static void main(String[] args) {///万年历的进化版//1、这个月的…

bert pytorch 序列标注_序列标注:Bi-LSTM + CRF

最近在做序列标注的相关任务,为了理解bi-lstm + crf的原理及细节,找了很多相关资料,以及代码实现,这里分享给大家并附上一些自己的理解。 CRF 相关资料推荐 关于crf,我看了很多资料,这里推荐几个 - 英文的crf tutorial - 李航的统计学习方法 这两个讲的很细,公式很多,很…

python中if语句求最大值_python 判断三个数字中的最大值实例代码

python 判断三个数字中的最大值&#xff0c;具体代码如下所示&#xff1a; #判断三个数中最大值 n1 int(input(please enter the firest number:)) n2 int(input(please enter the second number:)) n3 int(input(please enter the third number:)) max_num 0 if n1 > n2…

am335x otg-usb

任务: am335x一共有两个usb主机控制器&#xff0c;在天嵌的bsp中&#xff0c;一个配置为usb host ,一个配置为了usb otg。现在需要将otg也配置为host。 实际修改过程非常简单&#xff1a;将.config文件中&#xff0c;将CONFIG_USB_OTG&#xff0c;CONFIG_USB_OTG_WHITELIST&am…

Linux网络管理基本

子网掩码与IP地址同等长度&#xff0c;与IP地址每一位一一对应&#xff0c;IP地址中对应子网掩码为1的位为网络部分Linux中网卡标识为eth&#xff0c;第一块网卡叫做eth0&#xff0c;第二块叫做eth1&#xff0c;以此类推使用lspci或lsusb命令可查看网卡物理信息命令ifconfig (-…

python如果想测试变量的类型、可以使用_python里测试变量类型用什么

Python中测试变量类型可以使用isinstance()函数或type()函数来完成。 isinstance() 函数&#xff1a; isinstance()函数来判断一个对象是否是一个已知的类型&#xff0c;类似 type()。 isinstance()函数的语法:isinstance(object, classinfo) 参数&#xff1a; object -- 实例对…

参考文献起止页码怎么写_【求助】有全文参考文献但没有起止页码如何办

我的文章引用的文献中有5篇从PUBMED得到的全文电子版是没有起止页码的,在论文中参考文献的著录是要求起止页码的,这该如何办?这5篇文献如下,欢迎战友们伸出援手,1. Lpez-Revilla, R., Martnez-Contreras, L.-A., and Snchez-Garza, M. (2008): Prevalence of high-risk human…

平台系统云服务器配置,01-云平台连接配置

1云平台连接1.1 云平台连接简介云平台连接是指设备与H3C绿洲平台服务器(H3C Oasis server)通过Internet建立的远程管理通道。通过云平台连接&#xff0c;网络管理员可以在没有直接接入到设备所在网络的情况下&#xff0c;通过绿洲平台服务器对分布在不同地域的设备进行管理和维…

python 计算协方差矩阵_opencv2学习:计算协方差矩阵

图像的高级处理中&#xff0c;协方差矩阵计算是必不可少的&#xff0c;但opencv关于这方面的资料却相当少。首先&#xff0c;利用matlab计算一下&#xff0c;便于比较&#xff1a;>> data[1,2,3;10,20,30]data 1 2 310 20 30>> convarcov(data)convar 40.5000 81.0…

源码安装mysql5.1.51

1. ./mysql_install_db --force 2. 进入到mysql的安装目录执行下面4个命令 groupadd mysql useradd -g mysql mysql chown -R mysql . chgrp -R mysql . 3. 将源码里的my-medium.cnf文件拷贝到mysql的安装目录 cp support-files/my-medium.cnf etc/my.cnf 4. 执行…

python读取文件路径报invalid_关于Python读取文件的路径中斜杠问题

最近用Python读取文件&#xff0c;发现有时候用 \ 会报错&#xff0c;换成 \\ 就不会报错。查了下资料发现&#xff0c;\是Python的转义字符&#xff0c;如果路径中存在\t或者\r这样的特殊字符&#xff0c;\就无法起到目录跳转的作用&#xff0c;因此报错。解决办法就是告诉系统…

vb如何定义微软服务器stul,VBScrip微软官方教程.doc

VBScrip微软官方教程VBScript微软官方教程Microsoft Visual Basic Scripting Edition 是程序开发语言 Visual Basic 家族的最新成员&#xff0c;它将灵活的 Script 应用于更广泛的领域&#xff0c;包括 Microsoft Internet Explorer 中的 Web 客户机 Script 和 Microsoft Inter…

cocos2d-x for wp 之Box2D的应用

本文大部分内容是基于fengyun1989的博文&#xff0c;自己只是加深巩固而已 Box2d是一款用于2d游戏的物理引擎。在这个世界里创造出的物体都更接近于真实世界的物体。 首先&#xff0c;在项目添加Box2D.XNA.DLL。 新建一个页面BOX2DLayer并继承于CCLayer 重写init函数&#xff0…

qt 添加依赖库lib_在QT中添加LIB的方法

自动显示隐藏布局的listView借助View的OnTouchListener接口来监听listView的滑动,通过比较与上次坐标的大小,判断滑动方向,并通过滑动方向来判断是否需显示或者隐藏对应的布局,并且带有动画效果. 1.自动显示 ...ImFire即时通讯系统构建(需求)ImFire需求 一期需求(近期) 1.新用户…

python中集合运算_Python中的集合操作与集合运算

Python中的集合是一种无序的&#xff0c;无重复值的数据结构类型。Python中的集合可以用来检测元素检测或消除重复的元素。 一、python 集合概述 &#xff08;1&#xff09;Python中的集合元素是无序的&#xff0c;即元素没有顺序问题&#xff0c;也不能像数组、列表、字符串那…

Asp.net 定时任务

1.定时器 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; using System.Text; using System.Web.Security; using System.Web.SessionState; using System.Timers;namespace WebApplication1 {public class Global :…

arm64入栈出栈_ARM64的内核栈、用户栈、寄存器上下文

1. 内核栈的分配&#xff0c;即thread_info的分配&#xff0c;是在do_fork->dup_task_struct中分配(默认为2个pages)&#xff0c;并赋值给task_struct->stack&#xff1b;2. 用户栈的分配分两种&#xff1a;一是pthread create会事先mmap分配好用户栈&#xff0c;传给do_…