C# 基于消息发布订阅模型的示例(下)

我来为您详细讲解一下“C# 基于消息发布订阅模型的示例(下)” 的完整攻略。

什么是消息发布订阅模型?

消息发布订阅模型是一种消息传递模式,它包含一个发布者和许多订阅者。发布者通常不知道有哪些订阅者,而订阅者则可以动态地订阅和取消订阅发布者。

消息发布订阅模型的优势

  • 较容易增加或删除订阅者,无需修改发布者代码。
  • 可以实现一对多的关系,即一个事件可以有多个订阅者。
  • 发布者和订阅者之间松散耦合,使得系统更易于扩展和维护。

示例说明一:使用 RabbitMQ 实现基于消息发布订阅模型

要使用 RabbitMQ 实现消息发布订阅模型,需要引入 RabbitMQ 的消息中间件,并编写发布者和订阅者的代码。

首先需要创建一个名为 RabbitMQExample 的控制台应用程序,引入 RabbitMQ 的 NuGet 包。代码如下:

using RabbitMQ.Client;
using System;
using System.Text;

namespace RabbitMQExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(exchange: "logs", type: "fanout");

                var message = GetMessage(args);
                var body = Encoding.UTF8.GetBytes(message);
                channel.BasicPublish(exchange: "logs",
                                     routingKey: "",
                                     basicProperties: null,
                                     body: body);
                Console.WriteLine(" [x] Sent {0}", message);
            }

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }

        private static string GetMessage(string[] args)
        {
            return ((args.Length > 0)
                   ? string.Join(" ", args)
                   : "info: Hello World!");
        }
    }
}

这是发布者的代码,它将消息发布到指定的交换机。在这里,我们创建了一个名为 logs 的交换机,类型为 fanout。其他类型的交换机有 direct、topic 和 headers,但相较之下,fanout 类型的交换机不处理路由键而是简单地将消息广播到所有队列中。

然后,我们需要编写订阅者的代码。代码如下:

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace RabbitMQExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(exchange: "logs", type: "fanout");

                var queueName = channel.QueueDeclare().QueueName;
                channel.QueueBind(queue: queueName,
                                  exchange: "logs",
                                  routingKey: "");

                Console.WriteLine(" [*] Waiting for logs.");

                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body.ToArray();
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] {0}", message);
                };
                channel.BasicConsume(queue: queueName,
                                     autoAck: true,
                                     consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }
}

在这里我们同样创建一个名为 logs 的交换机,并创建一个随机的队列,将队列绑定到交换机上。这个代码块向我们展示了一个用于订阅并处理这些日志消息的简单示例。

运行代码的方式是,首先开启一个控制台窗口作为发布者,并输入需要发布的消息,然后点击回车确认发送。然后再开启一个控制台窗口作为订阅者,订阅这些消息并执行相应的处理逻辑。

示例说明二:使用 SignalR 实现基于消息发布订阅模型

如果你使用的是 ASP.NET Core,SignalR 可能是最简单的解决方案,因为它不需要引入额外的消息中间件,而是使用了自带的信道和远程调用机制。在 ASP.NET Core 中使用 SignalR,你需要添加以下 NuGet 包:Microsoft.AspNetCore.SignalR 和 Microsoft.AspNetCore.SignalR.Core。

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace SignalRExample.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

在这里,我们创建了一个名为 ChatHub 的 SignalR hub。当一个用户发送消息时,我们将广播这条消息到所有已连接的客户端。

在这里,hub 继承了 SignalR 的 Hub 类,它包含了一些方便的方法来管理客户端和服务器之间的连接状态。这个类中有一个 SendMessage 方法,该方法接收一个用户名和消息作为参数,并对所有已连接的客户端发送消息。

下面是一个简单的客户端文件:

"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

connection.on("ReceiveMessage", function (user, message) {
    var encodedMsg = user + " says " + message;
    var li = document.createElement("li");
    li.textContent = encodedMsg;
    document.getElementById("messagesList").appendChild(li);
});

connection.start().then(function () {
    document.getElementById("sendButton").addEventListener("click", function (event) {
        var user = document.getElementById("userInput").value;
        var message = document.getElementById("messageInput").value;
        connection.invoke("SendMessage", user, message).catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });
}).catch(function (err) {
    return console.error(err.toString());
});

这个 JavaScript 文件定义了一个名为 connection 的 HubConnection 对象,该对象用于与 ChatHub 进行通信。当一个用户发送消息时,所有已连接的客户端都会接收到该消息,并在网页上显示。

要使用此示例,你需要在 Startup.cs 文件中添加以下代码:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<ChatHub>("/chatHub");
});

在这个文件里,你需要添加 SignalR 中间件以配置 SignalR 端点。通过以下方式注册端点:

endpoints.MapHub<ChatHub>("/chatHub");

现在你可以运行你的 ASP.NET Core 应用程序,并打开两个浏览器窗口以模拟两个用户。在其中一个窗口中发送一条消息,你将会在两个窗口都看到这条消息的出现。

这些示例为你提供了一些基本的实现。不同的开发场景需要使用不同的解决方案。在实现消息发布订阅模型时,有许多其他可供选择的方案,例如:Windows Workflow Foundation、Apache Kafka、Azure Service Bus 等。您可以根据自己的需求和实际情况选择其中最适合的方案。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 基于消息发布订阅模型的示例(下) - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • 分析C# Dictionary的实现原理

    分析C# Dictionary的实现原理 前言 C#中的Dictionary是一种常见的数据结构,它能够高效地存储Key-Value形式的数据。在我们使用它的时候,也需要了解其内部实现原理。 实现原理 C#中的Dictionary内部实现是采用哈希表来存储数据的。哈希表是一种非常重要的数据结构,它可以通过哈希函数将Key转换成哈希码,然后将哈希码映射到一个固…

    C# 2023年5月15日
    00
  • C#实现页面GZip或Deflate压缩的方法

    C#实现页面GZip或Deflate压缩的方法 在网络传输过程中,页面传输速度往往是一个很关键的问题。为了提升页面的传输速度,我们可以使用GZip或Deflate压缩算法来压缩传输内容。 GZip压缩 1.引入命名空间 using System.IO.Compression; 2.修改全局.asax.cs文件,添加如下代码: protected void A…

    C# 2023年6月3日
    00
  • C#使用iCSharpcode进行文件压缩实现方法

    下面是“C#使用iCSharpcode进行文件压缩实现方法”的完整攻略。 1. 引入iCSharpcode.SharpZipLib库 在C#中使用iCSharpcode进行文件压缩需要引入其提供的SharpZipLib库。可以通过NuGet来引入,也可以直接下载安装至本地项目中。 2. 使用ZipOutputStream进行文件压缩 压缩一个文件可以使用如下…

    C# 2023年6月1日
    00
  • asp.net 大文件上传控件

    概述ASP.NET是微软推出的一组web应用程序框架和编程模型,用于创建动态网站、web应用程序和web服务。ASP.NET大文件上传控件在开发中非常有用。本文将详细介绍如何使用ASP.NET大文件上传控件。 下载和安装在开始使用ASP.NET大文件上传控件之前,我们需要先下载和安装它。可以从官方网站获取ASP.NET大文件上传控件的最新版本,解压缩文件,然…

    C# 2023年6月3日
    00
  • Winform中Treeview实现按需加载的方法

    一、Winform中Treeview实现按需加载的方法 Winform中的Treeview控件非常适合用于显示树形结构的数据,但如果树的层次比较多或者数据比较庞大,一次性将所有数据全部加载到TreeView中显然不太现实,这时就需要实现按需加载的功能,即当需要展开树节点时,才动态地加载该节点下的子节点。 实现按需加载需要以下几个步骤: 1.设置TreeVie…

    C# 2023年5月31日
    00
  • ASP.NET生成图形验证码的方法详解

    ASP.NET生成图形验证码的方法,可以通过以下步骤实现: 1. 引用命名空间 首先,在代码文件中引用命名空间: using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Web; usin…

    C# 2023年5月31日
    00
  • c# 多线程处理多个数据的方法

    在C#中,多线程处理多个数据是一种常见的需求,本文将详细介绍如何使用C#实现多线程处理多个数据的方法,包括代码实现和注意事项等。 方法一:使用Task类 在C#中,我们可以使用Task类来实现多线程处理多个数据。以下是一个简单的示例代码: using System; using System.Threading.Tasks; class Program { …

    C# 2023年5月15日
    00
  • C#通过不安全代码看内存加载的示例详解

    让我来给大家详细讲解一下“C#通过不安全代码看内存加载的示例详解”的完整攻略。 标题 在开始之前,我们需要给这篇攻略一个标准的标题。根据通常的写作规范,一个良好的标题应该简洁、直观、准确地表达文章的主要内容。因此,我们可以采用如下的格式来给这篇攻略取一个合适的标题: C#通过不安全代码看内存加载的示例详解 内容 在正式讲解之前,我们需要了解一下什么是不安全代…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部