当前位置: 首页 > news >正文

C# 与 C++ 跨进程通信:使用 RabbitMQ 实现消息队列通信

在这里插入图片描述

1. 前言

在分布式系统或跨语言系统中,消息队列是一种广泛使用的解决方案,用于在不同系统或程序之间实现异步通信。本文将探讨如何使用 RabbitMQ 在 C# 和 C++ 程序之间实现跨进程通信。RabbitMQ 是一种高效、可靠的消息代理,支持多种语言客户端,包括 C# 和 C++,能够帮助我们在两个不同的进程间传递数据。

2. 什么是 RabbitMQ?

在这里插入图片描述
RabbitMQ 是一个基于 AMQP(高级消息队列协议)的开源消息代理。它可以在不同的应用程序或服务之间传递消息,通过队列解耦系统中的发送方和接收方,使得异步处理和分布式架构的实现更加简单。

特点

  • 提供可靠的消息传输。
  • 支持多种语言客户端。
  • 支持队列持久化。
  • 支持消息确认和重试机制。

3. 实现 C# 和 C++ 间的通信流程

为了实现 C# 和 C++ 之间的通信,我们将使用 RabbitMQ 消息队列。以下是整体步骤:

  1. 配置 RabbitMQ 服务器:确保已安装并配置 RabbitMQ 服务器。
  2. 使用 C++ 发送消息:C++ 程序将连接到 RabbitMQ 并发送一条消息到指定的队列。
  3. 使用 C# 接收消息:C# 程序将连接到同一 RabbitMQ 队列并接收消息。

4. 环境准备

  1. 安装 RabbitMQ:确保 RabbitMQ 服务器已安装并在本地或远程运行。
  2. 安装客户端库
    • C++:使用 RabbitMQ C++ 客户端库。
    • C#:使用 RabbitMQ.Client NuGet 包。

5. 编码实现:使用 RabbitMQ 进行 C# 和 C++ 间的跨进程通信

1. C++ 代码:发送和接收消息

结合我们前面的文章 C++开发基础之使用librabbitmq库实现RabbitMQ消息队列通信。在C++ 程序使用 RabbitMQ 客户端库发送消息。

2. C# 代码:发送和接收消息

C#发送消息的示例

C#发送端实现将消息发送到 RabbitMQ 服务器,并通过指定的交换机进行路由:

  1. 配置连接:设置 RabbitMQ 服务器地址 (localhost)、端口(5672)、交换机名称 (example_exchange)、路由键 (example_key) 和消息内容。

  2. 创建连接与频道:通过 ConnectionFactory 创建连接和通信频道。

  3. 声明交换机:通过 channel.ExchangeDeclare 声明一个 direct 类型的交换机,确保交换机存在。

  4. 发送消息:将消息转换为字节数组并使用 channel.BasicPublish 将消息发送到指定的交换机,使用指定的路由键进行路由。

  5. 输出日志:控制台打印发送的消息内容。

using RabbitMQ.Client;
using System.Text;namespace MQCSharpApp
{internal class Program{static void Main(string[] args){// 连接RabbitMQ服务器的配置string hostname = "localhost";  // RabbitMQ 服务器地址int port = 5672;  // RabbitMQ 默认端口string exchange = "example_exchange";  // 交换机名称string routingKey = "example_key";  // 路由键// 创建连接工厂并设置连接参数var factory = new ConnectionFactory() { HostName = hostname, Port = port };using (var connection = factory.CreateConnection())using (var channel = connection.CreateModel()){// 声明一个交换机(确保交换机已经存在,类型为direct)channel.ExchangeDeclare(exchange, ExchangeType.Direct);int messageCount = 1;// 定时发送消息Timer timer = new Timer((e) =>{// 准备消息内容string message = $"Hello from C#! Message number: {messageCount++}";var body = Encoding.UTF8.GetBytes(message);// 发布消息到交换机channel.BasicPublish(exchange: exchange,routingKey: routingKey,basicProperties: null,body: body);Console.WriteLine($" [x] Sent: {message}");}, null, 0, 1000); // 每隔 1 秒发送一次Console.WriteLine("Press [enter] to exit.");Console.ReadLine();  // 保持程序运行直到按下 Enter}}}
}

执行步骤和运行结果:

  1. 启动 C++ 程序:执行 C++ 程序,使其在交换机 example_exchange 上监听消息。
  2. 运行 C# 程序:执行 C# 程序,定时发送一条消息到 RabbitMQ 队列。
  3. C++ 程序收到来自C#程序发送的消息,并在控制台中显示。

在这里插入图片描述

C# 接收消息的示例

C#创建接收端:

  1. 创建连接和频道:与发送者的程序类似,创建了一个连接工厂,连接到 RabbitMQ 服务器,并建立一个频道。
  2. 声明交换机:与发送者一致,声明了一个类型为 direct 的交换机。
  3. 声明队列:在消费者端声明了一个队列(example_queue)。如果队列已经存在,它不会重新创建。
  4. 队列与交换机绑定:通过 QueueBind 将队列与交换机绑定,使用 routingKey 来进行消息路由。
  5. 事件消费者:创建了一个 EventingBasicConsumer 来接收消息。当有消息到达时,consumer.Received 事件会被触发,消息内容会被打印到控制台。
  6. 开始消费消息:通过 BasicConsume 启动消息的消费,这会让程序进入等待接收消息的状态,直到按下 Ctrl+C 停止。
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;namespace MQCSharpApp
{internal class Program{static void Main(string[] args){// 连接RabbitMQ服务器的配置string hostname = "localhost";  // RabbitMQ 服务器地址int port = 5672;  // RabbitMQ 默认端口string exchange = "example_exchange";  // 交换机名称string routingKey = "example_key";  // 路由键string queueName = "example_queue";  // 队列名称// 创建连接工厂并设置连接参数var factory = new ConnectionFactory() { HostName = hostname, Port = port };using (var connection = factory.CreateConnection())using (var channel = connection.CreateModel()){// 声明一个交换机(确保交换机已经存在,类型为direct)channel.ExchangeDeclare(exchange, ExchangeType.Direct);// 声明一个队列,并确保队列存在channel.QueueDeclare(queue: queueName,durable: false,exclusive: false,autoDelete: false,arguments: null);// 将队列与交换机绑定channel.QueueBind(queue: queueName,exchange: exchange,routingKey: routingKey);Console.WriteLine(" [*] Waiting for messages. To exit press [CTRL+C]");// 创建一个事件消费者来接收消息var consumer = new EventingBasicConsumer(channel);consumer.Received += (model, ea) =>{var body = ea.Body.ToArray();var message = Encoding.UTF8.GetString(body);Console.WriteLine($" [x] Received: {message}");};// 开始消费消息channel.BasicConsume(queue: queueName,autoAck: true,  // 自动确认消息consumer: consumer);// 保持程序运行,直到按下 CTRL+CConsole.ReadLine();}}}
}

执行步骤和运行结果:

  1. 启动 C# 程序: 执行 C# 程序,使其在交换机 example_exchange 上监听消息。
  2. 运行 C++程序:执行 C++ 程序,定时发送一条消息到 RabbitMQ 队列。
  3. C#程序收到来自 C++程序的消息,并在控制台中显示。
    在这里插入图片描述

6. C# 和 C++ 跨进程通信的机制分析

优势

  • 解耦:消息队列解耦了消息的发送方和接收方,使得两者可以独立开发、部署和运行。
  • 异步通信:消息队列允许异步通信,发送方不需要等待接收方的响应。
  • 跨语言支持:RabbitMQ 提供了多种语言客户端,适用于多语言环境中的通信需求。

7. 适用场景

  • 异步任务:比如日志处理、异步计算等任务,发送方将任务消息发送到队列,接收方从队列中读取并处理任务。
  • 分布式系统通信:在不同服务之间实现消息传递和事件驱动。
  • 任务队列:多个消费者从同一队列读取消息进行负载均衡。

8. 总结

本文介绍了如何使用 RabbitMQ 实现 C# 和 C++ 之间的跨进程通信,通过消息队列传递消息。这种方式非常适用于异步、跨语言的通信需求。RabbitMQ 为消息的可靠传输提供了保障,并支持消息的持久化。

在下一篇文章中,我们将探讨如何使用 WebApi 实现 C# 和 C++ 之间的直接通信,以及其在性能和复杂性方面的差异。


http://www.mrgr.cn/news/68181.html

相关文章:

  • 【362】基于springboot的在线租房和招聘平台
  • 华为HCIP —— QinQ技术实验配置
  • 5分钟利用SD+剪映制作爆款的山水画艺术体视频,快速涨粉(含完整的操作步骤)
  • layui 自定义验证单选框必填
  • 安利一款超6K+ star的可拖放响应式灵活的网格布局Gridstack.js
  • 基于IM场景下的Wasm初探:提升Web应用性能|得物技术
  • Golang | Leetcode Golang题解之第547题身份数量
  • API网关之Gravitee
  • 基于ViT的无监督工业异常检测模型汇总
  • 如何在 Linux 系统中通过进程名杀掉蓝牙进程
  • Meta AI最新推出的长视频语言理解多模态模型LongVU分享
  • Verilog可综合语法
  • C语言 | Leetcode C语言题解之第546题移除盒子
  • SQLI LABS | Less-32 GET-Bypass Custom Filter Adding Slashes To Dangerous Chars
  • B+树与聚簇索引以及非聚簇索引的关系
  • C++ | Leetcode C++题解之第546题移除盒子
  • Docker部署Redis主从复制
  • 看了《逆行人生》,我想到的是程序员的出路不只有外卖员,转型自媒体博主:或许是技术与内容的双向奔赴
  • Golang | Leetcode Golang题解之第546题移除盒子
  • 【划分型 DP】力扣139. 单词拆分
  • C++类的多重继承演示
  • 一文透彻了解电容
  • 机器学习(五)——支持向量机SVM(支持向量、间隔、正则化参数C、误差容忍度ε、核函数、软间隔、SVR、回归分类源码)
  • 解决中文乱码问题:常见原因与解决方案
  • 【我的世界】宠物不认我了?怎么更换主人?(Java版)
  • STM32外设应用研究