.net使用cap实现消息异步处理

 更新时间:2024年05月17日 10:05:15   作者:假装我不帅  
CAP 是一个基于 .NET Standard 的 C# 库,它是一种处理分布式事务的解决方案,同样具有 EventBus 的功能,它具有轻量级、易使用、高性能等特点,本文给大家介绍了.net下使用cap实现消息异步处理,需要的朋友可以参考下

介绍

CAP 是一个基于 .NET Standard 的 C# 库,它是一种处理分布式事务的解决方案,同样具有 EventBus 的功能,它具有轻量级、易使用、高性能等特点。

新建项目

新建.net7web项目

安装依赖包

安装软件

安装redis和Sql Server

修改代码

新建RedisConfigModel

namespace CAPStu01.Models;

public class RedisConfigModel
{
    /// <summary>
    /// 服务器地址
    /// </summary>
    public string Host { get; set; }

    /// <summary>
    /// 端口号
    /// </summary>
    public int Port { get; set; }

    /// <summary>
    /// 密码
    /// </summary>
    public string Pwd { get; set; }
}

修改appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "SQlServer": "server=127.0.0.1;User ID=sa;Password=xxxx;database=capstu;Encrypt=True;TrustServerCertificate=True;connection timeout=600;"
  },
  "RedisConfig": {
    "Host": "127.0.0.1",
    "Port": 6379,
    "Pwd": ""
  }
}

修改Program.cs

using CAPStu01.Models;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var redisConfig = builder.Configuration.GetSection("RedisConfig").Get<RedisConfigModel>();
var connectionStr = builder.Configuration.GetConnectionString("SQlServer") ?? "";
builder.Services.AddCap(x =>
{
    x.UseRedis(options =>
    {
        if (options.Configuration != null && redisConfig != null)
        {
            options.Configuration.EndPoints.Add(redisConfig.Host, redisConfig.Port);
            options.Configuration.DefaultDatabase = 0;
            options.Configuration.Password = redisConfig?.Pwd ?? "";
        }
    });
    x.UseSqlServer(sqlServerOptions =>
    {
        sqlServerOptions.Schema = "dbo";
        sqlServerOptions.ConnectionString = connectionStr;
    });
    //开启面板
    x.UseDashboard(d =>
    {
        //允许匿名访问
        d.AllowAnonymousExplicit = true;
    });
});
var app = builder.Build();

app.UseRouting();
app.MapControllers();
app.Run();

新建HomeController

using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc;

namespace CAPStu01.Controllers;

[ApiController]
public class HomeController:ControllerBase
{
    public HomeController()
    {
        
    }

    /// <summary>
    /// 发送消息
    /// </summary>
    /// <returns></returns>
    [HttpGet("/")]
    public IActionResult Index([FromServices]ICapPublisher capBus)
    {
        capBus.Publish("test.show.time","你好,CAP");
        return Content("发送消息成功");
    }
    
    /// <summary>
    /// 接受消息
    /// </summary>
    /// <param name="data"></param>
    [NonAction]
    [CapSubscribe("test.show.time")]
    public void ReceiveMessage(string data)
    {
        Console.WriteLine("message data is:" + data);
    }
}

结果

如果使用redis需要定期清理streams内容

安装freeredis,修改Program.cs

builder.Services.AddSingleton<IRedisClient>(new RedisClient($"{redisConfig.Host}:{redisConfig.Port},password={redisConfig.Pwd},defaultDatabase=0"));

新增清除方法

private readonly IRedisClient _redisClient;

public HomeController(IRedisClient redisClient)
{
    _redisClient = redisClient;
}

/// <summary>
/// 清除已处理的redis数据
/// </summary>
/// <returns></returns>
[HttpGet("/clear")]
public IActionResult ClearAckStream()
{
    var groups = _redisClient.XInfoGroups("test.show.time");
    var unreandMsgs = new List<string>();
    //获取所有的未读消息
    foreach (var group in groups)
    {
        if (group.pending > 0)
        {
            //有未读消息
            var unReadList = _redisClient.XPending("test.show.time", group.name);
            if (unReadList.count > 0)
            {
                var groupInfo = _redisClient.XPending("test.show.time", group.name);
                var unreandList = _redisClient.XPending("test.show.time", group.name, groupInfo.minId, groupInfo.maxId,
                    groupInfo.count);
                foreach (var unre in unreandList)
                {
                    unreandMsgs.Add(unre.id);
                }
            }
        }
    }
    //获取全部的消息
    var allMsgs = _redisClient.XRange("test.show.time", "-", "+");
    foreach (var msg in allMsgs)
    {
        if (unreandMsgs.Contains(msg.id))
        {
            //这个消息未读则跳过
            continue;
        }
        //删除已处理的消息
        _redisClient.XDel("test.show.time", msg.id);
    }

    return Content($"共处理未读消息:{unreandMsgs.Count}个,已读消息{allMsgs.Length}个");
}

以上就是.net使用cap实现消息异步处理的详细内容,更多关于.net cap消息处理的资料请关注脚本之家其它相关文章!

相关文章

  • 完成OSS.Http底层HttpClient重构封装 支持标准库

    完成OSS.Http底层HttpClient重构封装 支持标准库

    OSS.Http项目对于.Net Standard标准库的支持已经迁移完毕,OSS开源系列两个最底层的类库已经具备跨运行时支持的能力。本篇文章主要包含 1. HttpClient的介绍,2. 重构的思路, 3. 容易遇到的问题。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • C#队列Queue多线程用法实例

    C#队列Queue多线程用法实例

    这篇文章主要介绍了C#队列Queue多线程用法,实例分析了队列的相关使用技巧,需要的朋友可以参考下
    2015-05-05
  • C#中如何使用Chart图表问题

    C#中如何使用Chart图表问题

    这篇文章主要介绍了C#中如何使用Chart图表问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • c#自带缓存使用方法 c#移除清理缓存

    c#自带缓存使用方法 c#移除清理缓存

    这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下
    2014-02-02
  • C#遍历文件夹获取指定后缀名文件

    C#遍历文件夹获取指定后缀名文件

    这篇文章主要为大家详细介绍了C#遍历文件夹获取指定后缀名文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • C#使用CefSharp实现内嵌网页详解

    C#使用CefSharp实现内嵌网页详解

    这篇文章主要介绍了C# WPF里怎么使用CefSharp嵌入一个网页,并给出一个简单示例演示C#和网页(JS)的交互实现,感兴趣的小伙伴可以了解一下
    2023-04-04
  • C# 执行Javascript脚本的方法步骤

    C# 执行Javascript脚本的方法步骤

    本文主要介绍了C# 执行Javascript脚本的方法步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C#调用Win32的API函数--User32.dll

    C#调用Win32的API函数--User32.dll

    这篇文章主要介绍了C#调用Win32_的API函数--User32.dll,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • C#定时器Timer实现精确到1-2毫秒以内

    C#定时器Timer实现精确到1-2毫秒以内

    最近在排查项目OTA的一个问题,触发了一毫秒或者2毫秒执行一次进程间通信的,导致通信阻塞的问题,这样就需要用到模拟触发1ms或者2ms触发事件,所以本文给大家介绍了C# 定时器 Timer 如何精确到 1-2 毫秒以内,需要的朋友可以参考下
    2024-12-12
  • C#实现启用与禁用本地网络的方式小结【3种方式】

    C#实现启用与禁用本地网络的方式小结【3种方式】

    这篇文章主要介绍了C#实现启用与禁用本地网络的方式,结合实例形式总结分析了使用Hnetcfg.dll、Shell32.dll及setupapi.dll三种启用与禁用本地网络的操作方法,需要的朋友可以参考下
    2016-07-07

最新评论