zoukankan      html  css  js  c++  java
  • RabbitMQ学习模拟超时支付场景代码(ASP.NET Core)

    一.项目结构

        

    二 类库Infrastructure代码

    添加nuget引用:RabbitMQ.Client,引用项目Rabbit.Entities

    1.RabbitOption.cs代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Config
    {
        public class RabbitOption
        {
            /// <summary>
            /// 主机名称
            /// </summary>
            public string HostName { get; set; }
            public string Address { get; set; }
            /// <summary>
            /// 端口号
            /// </summary>
            public int Port { get; set; }
            public string UserName { get; set; }
            public string Password { get; set; }
    
            public string VirtualHost { get; set; }
        }
    }

    2.RabbitConnection.cs代码

    using RabbitMQ.Client;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Config
    {
        public class RabbitConnection
        {
            private readonly RabbitOption _config;
            private IConnection _connection = null;
            public RabbitConnection(RabbitOption rabbitOption)
            {
                _config = rabbitOption;
            }
    
            public IConnection GetConnection()
            {
                if (_connection == null)
                {
                    if (string.IsNullOrEmpty(_config.Address))
                    {
                        ConnectionFactory factory = new ConnectionFactory();
                        factory.HostName = _config.HostName;
                        factory.Port = _config.Port;
                        factory.UserName = _config.UserName;
                        factory.Password = _config.Password;
                        factory.VirtualHost = _config.VirtualHost;
                        _connection = factory.CreateConnection();
                    }
                    else
                    {
                        ConnectionFactory factory = new ConnectionFactory();
                        factory.UserName = _config.UserName;
                        factory.Password = _config.Password;
                        factory.VirtualHost = _config.VirtualHost;
    
                        var address = _config.Address;
                        List<AmqpTcpEndpoint> endpoints = new List<AmqpTcpEndpoint>();
                        foreach (var endpoint in address.Split(","))
                        {
                            endpoints.Add(new AmqpTcpEndpoint(endpoint.Split(":")[0],int.Parse(endpoint.Split(":")[1])));
                        }
                        _connection = factory.CreateConnection(endpoints);
                    }
                }
                return _connection;
            }
        }
    }

    3.RabbitConstant.cs代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Config
    {
        public class RabbitConstant
        {
            public const string TEST_EXCHANGE = "test.exchange";
            public const string TEST_QUEUE = "test.queue";
    
            public const string DELAY_EXCHANGE = "delay.exchange";
            public const string DELAY_ROUTING_KEY = "delay.routing.key";
            public const string DELAY_QUEUE = "delay.queue";
    
            public const string DEAD_LETTER_EXCHANGE = "dead.letter.exchange";
            public const string DEAD_LETTER_QUEUE = "dead.letter.queue";
            public const string DEAD_LETTER_ROUTING_KEY = "dead.letter.routing.key";
        }
    }

    4.QueueInfo.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Consumer
    {
        public class QueueInfo
        {
            /// <summary>
            /// 队列名称
            /// </summary>
            public string Queue { get; set; }
            /// <summary>
            /// 路由名称
            /// </summary>
            public string RoutingKey { get; set; }
            /// <summary>
            /// 交换机类型
            /// </summary>
            public string ExchangeType { get; set; }
            /// <summary>
            /// 交换机名称
            /// </summary>
            public string Exchange { get; set; }
            public IDictionary<string, object> props { get; set; } = null;
            public Action<RabbitMessageEntity> OnRecevied { get; set; }
        }
    }

    5.RabbitChannelConfig.cs

    using RabbitMQ.Client;
    using RabbitMQ.Client.Events;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Consumer
    {
        public class RabbitChannelConfig
        {
            public string ExchangeTypeName { get; set; }
            public string ExchangeName { get; set; }
            public string QueueName { get; set; }
            public string RoutingKeyName { get; set; }
            public IConnection Connection { get; set; }
            public EventingBasicConsumer Consumer { get; set; }
    
            /// <summary>
            /// 外部订阅消费者通知委托
            /// </summary>
            public Action<RabbitMessageEntity> OnReceivedCallback { get; set; }
    
            public RabbitChannelConfig(string exchangeType,string exchange,string queue,string routingKey)
            {
                this.ExchangeTypeName = exchangeType;
                this.ExchangeName = exchange;
                this.QueueName = queue;
                this.RoutingKeyName = routingKey;
            }
    
            public void Receive(object sender,BasicDeliverEventArgs args)
            {
                RabbitMessageEntity body = new RabbitMessageEntity();
                try
                {
                    string content = Encoding.UTF8.GetString(args.Body.ToArray());
                    body.Content = content;
                    body.Consumer =(EventingBasicConsumer)sender;
                    body.BasicDeliver = args;
                }
                catch (Exception e)
                {
                    body.ErrorMessage = $"订阅出错{e.Message}";
                    body.Exception = e;
                    body.Error = true;
                    body.Code = 500;
                }
                OnReceivedCallback?.Invoke(body);
            }
        }
    }

    6.RabbitChannelManager.cs

    using Infrastructure.Config;
    using RabbitMQ.Client;
    using RabbitMQ.Client.Events;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Consumer
    {
        public class RabbitChannelManager
        {
            public RabbitConnection Connection { get; set; }
    
            public RabbitChannelManager(RabbitConnection connection)
            {
                this.Connection = connection;
            }
    
            /// <summary>
            /// 创建接收消息的通道
            /// </summary>
            /// <param name="exchangeType"></param>
            /// <param name="exchange"></param>
            /// <param name="queue"></param>
            /// <param name="routingKey"></param>
            /// <param name="arguments"></param>
            /// <returns></returns>
            public RabbitChannelConfig CreateReceiveChannel(string exchangeType,string exchange,string queue,string routingKey,
                IDictionary<string,object>arguments = null)
            {
                IModel model = this.CreateModel(exchangeType,exchange,queue,routingKey,arguments);
                EventingBasicConsumer consumer = this.CreateConsumer(model,queue);
                RabbitChannelConfig channel = new RabbitChannelConfig(exchangeType,exchange,queue,routingKey);
                consumer.Received += channel.Receive;
                return channel;
            }
    
          
            /// <summary>
            /// 创建一个通道,包含交换机/队列/路由,并建立绑定关系
            /// </summary>
            /// <param name="exchangeType">交换机类型:Topic,Direct,Fanout</param>
            /// <param name="exchange">交换机名称</param>
            /// <param name="queue">队列名称</param>
            /// <param name="routingKey">路由名称</param>
            /// <param name="arguments"></param>
            /// <returns></returns>
            private IModel CreateModel(string exchangeType, string exchange, string queue, string routingKey, IDictionary<string, object> arguments)
            {
                exchangeType = string.IsNullOrEmpty(exchangeType) ? "default" : exchangeType;
                IModel model = this.Connection.GetConnection().CreateModel();
                model.BasicQos(0,1,false);
                model.QueueDeclare(queue,true,false,false,arguments);
                model.ExchangeDeclare(exchange, exchangeType);
                model.QueueBind(queue, exchange, routingKey);
                return model;
            }
    
            /// <summary>
            /// 创建消费者
            /// </summary>
            /// <param name="model"></param>
            /// <param name="queue"></param>
            /// <returns></returns>
            private EventingBasicConsumer CreateConsumer(IModel model, string queue)
            {
                EventingBasicConsumer consumer = new EventingBasicConsumer(model);
                model.BasicConsume(queue, false, consumer);
                return consumer;
            }
        }
    }

    7.RabbitMessageEntity.cs

    using RabbitMQ.Client.Events;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Consumer
    {
        public class RabbitMessageEntity
        {
            public string Content { get; set; }
            public EventingBasicConsumer Consumer { get; set; }
            public BasicDeliverEventArgs BasicDeliver { get; set; }
            public string ErrorMessage { get; set; }
            public Exception Exception { get; set; }
            public bool Error { get; set; }
            public int Code { get; set; }
        }
    }

    8.OrderMessage.cs

    using RabbitMQ.Entities;
    
    namespace Infrastructure.Message
    {
        public class OrderMessage
        {
            public Account Account { get; set; }
            public OrderInfo OrderInfo { get; set; }
        }
    }

    9.IRabbitProducer.cs

    using System;
    using System.Collections.Generic;
    
    namespace Infrastructure.Producer
    {
        public interface IRabbitProducer
        {
            public void Publish(string exchange,string routingKey,IDictionary<string,object> props,string content);
        }
    }

    10.RabbitProducer.cs

    using Infrastructure.Config;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Infrastructure.Producer
    {
        public class RabbitProducer : IRabbitProducer
        {
            private readonly RabbitConnection _connection;
            public RabbitProducer(RabbitConnection connection)
            {
                _connection = connection;
            }
            public void Publish(string exchange, string routingKey, IDictionary<string, object> props, string content)
            {
                var channel = _connection.GetConnection().CreateModel();
         
                var prop = channel.CreateBasicProperties();
                if (props.Count > 0)
                {
                    var delay = props["x-delay"];
                    prop.Expiration = delay.ToString();
                }
                channel.BasicPublish(exchange, routingKey, false, prop, Encoding.UTF8.GetBytes(content));
            }
        }
    }

    三 类库RabbitMQ.Entities代码

    1.Account.cs

    using System;
    
    namespace RabbitMQ.Entities
    {
        public class Account
        {
            public string UserName { get; set; }
            public string Password { get; set; }
            public string Email { get; set; }
            public string Phone { get; set; }
        }
    }

    2.OrderInfo.cs

    using System;
    
    namespace RabbitMQ.Entities
    {
        public class OrderInfo
        {
            public int GoodsCount { get; set; }
            public int GoodsId { get; set; }
            public string GoodsName { get; set; }
            public int Status { get; set; }
            public int UserId { get; set; }
        }
    }

    四 类库RabbitMQ.Services代码

    引用:nuget添加Newtonsoft.Json,添加项目Infrastructure、RabbitMQ.Entities引用

    1.IOrderService.cs

    using System;
    
    namespace RabbitMQ.Services
    {
        public interface IOrderService
        {
            void SendOrderMessage();
            void SendTestMessage(string message);
        }
    }

    2.OrderService.cs

    using Infrastructure.Config;
    using Infrastructure.Producer;
    using System;
    using System.Collections.Generic;
    using System.Text;
    using RabbitMQ.Entities;
    using Newtonsoft.Json;
    using Infrastructure.Message;
    
    namespace RabbitMQ.Services
    {
        public class OrderService : IOrderService
        {
            private readonly IRabbitProducer _rabbitProducer;
            public OrderService(IRabbitProducer rabbitProducer)
            {
                _rabbitProducer = rabbitProducer;
            }
            public void SendOrderMessage()
            {
                OrderInfo orderInfo = new OrderInfo();
                orderInfo.GoodsCount = 1;
                orderInfo.GoodsId = 1;
                orderInfo.GoodsName = "大话设计模式";
                orderInfo.Status = 0;
                orderInfo.UserId = 1;
                Account account = new Account();
                account.UserName = "Hobelee";
                account.Password = "password007";
                account.Email = "hobelee@163.com";
                account.Phone = "13964836342";
                OrderMessage orderMessage = new OrderMessage();
                orderMessage.Account = account;
                orderMessage.OrderInfo = orderInfo;
                string message = JsonConvert.SerializeObject(orderMessage);
                Console.WriteLine("短信/邮件异步通知");
                Console.WriteLine($"send message:{message}");
                //支付服务
                _rabbitProducer.Publish(RabbitConstant.DELAY_EXCHANGE, RabbitConstant.DELAY_ROUTING_KEY,
                    new Dictionary<string, object>()
                    {
                        { "x-delay",1000*20}
                    },message);
            }
    
            public void SendTestMessage(string message)
            {
                Console.WriteLine($"send message:{message}");
                _rabbitProducer.Publish(RabbitConstant.TEST_EXCHANGE,"",new Dictionary<string,object>(),message);
            }
        }
    }

    3.IPayService.cs

    using RabbitMQ.Entities;
    
    namespace RabbitMQ.Services
    {
        public interface IPayService
        {
            void UpdateOrderPayState(OrderInfo orderInfo);
        }
    }

    4.PayService.cs

    using RabbitMQ.Entities;
    using System;
    
    namespace RabbitMQ.Services
    {
        public class PayService : IPayService
        {
            public void UpdateOrderPayState(OrderInfo orderInfo)
            {
                Console.WriteLine($"修改订单状态:{orderInfo.Status}");
            }
        }
    }

    五 ASP.NET Core Web API项目RabbitMQ.WebApi.Order代码

    引用:添加项目引用Infrastructure、RabbitMQ.Services

    1.appsettins.json

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "RabbitMQ": {
        "HostName": "127.0.0.1",
        "Address": "",
        "Port": 5672,
        "UserName": "guest",
        "Password": "guest",
        "VirtualHost": "/"
      },
    
      "AllowedHosts": "*"
    }

    2.ServiceExtensions.cs

    using Infrastructure.Config;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace RabbitMQ.WebApi.Order.Extensions
    {
        public static class ServiceExtensions
        {
            public static void ConfigureCors(this IServiceCollection services)
            {
                services.AddCors(options=>
                {
                    options.AddPolicy("AnyPolicy",
                        builder=>builder.AllowAnyOrigin()
                                        .AllowAnyMethod()
                                        .AllowAnyHeader());
                });
            }
            public static void ConfigureRabbitContext(this IServiceCollection services,IConfiguration config)
            {
                var section = config.GetSection("RabbitMQ");
                services.AddSingleton(
                      new RabbitConnection(section.Get<RabbitOption>())); 
            }
        }
    }

    3.Startup.cs

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using RabbitMQ.WebApi.Order.Extensions;
    using Microsoft.OpenApi.Models;
    using RabbitMQ.Services;
    using Infrastructure.Producer;
    
    namespace RabbitMQ.WebApi.Order
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
                services.AddSwaggerGen(c=>
                {
                    c.SwaggerDoc("v1",new OpenApiInfo { Title="RabbitMQ.WebApi.Order",Version="v1"});
                });
                services.AddScoped<IOrderService, OrderService>();
                services.AddScoped<IRabbitProducer,RabbitProducer>();
                services.ConfigureCors();
                services.ConfigureRabbitContext(Configuration);
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseSwagger();
                    app.UseSwaggerUI(c=>c.SwaggerEndpoint("/swagger/v1/swagger.json","RabbitMQ.WebApi.Order v1"));
                }
    
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
        }
    }

    六 控制台项目RabbitMQ.Pay代码

    添加nuget引用:Microsoft.Extensions.Hosting,Newtonsoft.Json

    添加项目引用:Infrastructure,RabbitMQ.Services

    将项目RabbitMQ.WebApi.Order中的appsettings.json文件复制到该项目

    1.ProcessPay.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Infrastructure.Config;
    using Infrastructure.Consumer;
    using Infrastructure.Message;
    using Microsoft.Extensions.Hosting;
    using Newtonsoft.Json;
    using RabbitMQ.Client;
    using RabbitMQ.Entities;
    using RabbitMQ.Services;
    
    namespace RabbitMQ.Pay
    {
        public class ProcessPay : IHostedService
        {
            private readonly RabbitConnection _connection;
            private readonly IPayService _payService;
            public List<RabbitChannelConfig> Channels { get; set; }
            public List<QueueInfo> Queues { get; } = new List<QueueInfo>();
            public ProcessPay(RabbitConnection connection, IPayService payService)
            {
                _connection = connection;
                _payService = payService;
                Queues.Add(new QueueInfo()
                { 
                   ExchangeType = ExchangeType.Direct,
                   Exchange = RabbitConstant.DELAY_EXCHANGE,
                   Queue = RabbitConstant.DELAY_QUEUE,
                   RoutingKey = RabbitConstant.DELAY_ROUTING_KEY,
                   props = new Dictionary<string, object>()
                   {
                       { "x-dead-letter-exchange",RabbitConstant.DEAD_LETTER_EXCHANGE},
                       { "x-dead-letter-routing-key",RabbitConstant.DEAD_LETTER_ROUTING_KEY}
                   },
                   OnRecevied = this.Receive
                });
            }
    
            private void Receive(RabbitMessageEntity message)
            {
                Console.WriteLine($"Pay Receive Message:{message.Content}");
                OrderMessage orderMessage = JsonConvert.DeserializeObject<OrderMessage>(message.Content);
    
                //超时未支付
                string money = "";
                //支付处理
                Console.WriteLine("请输入:");
                //超时未支付进行处理
                Task.Run(()=>
                {
                    money = Console.ReadLine();
                }).Wait(20*1000);
                if (string.Equals(money, "100"))
                {
                    //设置状态为支付成功(同时设置消息的状态和数据库订单的状态)
                    orderMessage.OrderInfo.Status = 1;
                    _payService.UpdateOrderPayState(orderMessage.OrderInfo);
                    Console.WriteLine("支付完成");
                    message.Consumer.Model.BasicAck(deliveryTag:message.BasicDeliver.DeliveryTag,multiple:true);
                }
                else
                {
                    //重试几次依然失败
                    Console.WriteLine("等待一定时间失效超时未支付的订单");
                    //消息进入到死信队列
                    message.Consumer.Model.BasicNack(deliveryTag: message.BasicDeliver.DeliveryTag,
                                                      multiple: false,
                                                      requeue: false);
                }
            }
    
            public Task StartAsync(CancellationToken cancellationToken)
            {
                Console.WriteLine("RabbitMQ支付通知处理服务已启动");
                RabbitChannelManager channelManager = new RabbitChannelManager(_connection);
                foreach (var queueInfo in Queues)
                {
                    RabbitChannelConfig channel = channelManager.CreateReceiveChannel(queueInfo.ExchangeType,
                        queueInfo.Exchange,queueInfo.Queue,queueInfo.RoutingKey,queueInfo.props);
                    channel.OnReceivedCallback = queueInfo.OnRecevied;
                }
                return Task.CompletedTask;
            }
    
            public Task StopAsync(CancellationToken cancellationToken)
            {
                return Task.CompletedTask;
            }
        }
    }

    2.Program.cs

    using Infrastructure.Config;
    using Infrastructure.Producer;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using RabbitMQ.Services;
    using System;
    
    namespace RabbitMQ.Pay
    {
        class Program
        {
            static void Main(string[] args)
            {
                var configRabbit = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json")
                    .Build()
                    .GetSection("RabbitMQ");
                var host = new HostBuilder()
                    .ConfigureServices(services=>
                    services.AddSingleton(new RabbitConnection(configRabbit.Get<RabbitOption>()))
                    .AddSingleton<IHostedService,ProcessPay>()
                    .AddScoped<IRabbitProducer,RabbitProducer>()
                    .AddScoped<IPayService,PayService>()).Build();
                host.Run();
            }
        }
    }

    七 控制台RabbitMQ.Pay.Timeout项目代码

    添加nuget引用:Microsoft.Extensions.Hosting,Newtonsoft.Json

    添加项目引用:Infrastructure,RabbitMQ.Services

    将项目RabbitMQ.WebApi.Order中的appsettings.json文件复制到该项目

    1.ProcessPayTimeout.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Infrastructure.Config;
    using Microsoft.Extensions.Hosting;
    using Newtonsoft.Json;
    using RabbitMQ.Services;
    using Infrastructure.Consumer;
    using RabbitMQ.Client;
    using RabbitMQ.Entities;
    using Infrastructure.Message;
    
    namespace RabbitMQ.Pay.Timeout
    {
        public class ProcessPayTimeout : IHostedService
        {
            private readonly RabbitConnection _connection;
            private readonly IPayService _payService;
            public List<RabbitChannelConfig> Channels { get; set; } = new List<RabbitChannelConfig>();
            public List<QueueInfo> Queues { get; } = new List<QueueInfo>();
            public ProcessPayTimeout(RabbitConnection connection,IPayService payService)
            {
                _connection = connection;
                _payService = payService;
                Queues.Add(new QueueInfo
                { 
                   ExchangeType = ExchangeType.Direct,
                   Exchange = RabbitConstant.DEAD_LETTER_EXCHANGE,
                   Queue = RabbitConstant.DEAD_LETTER_QUEUE,
                   RoutingKey = RabbitConstant.DEAD_LETTER_ROUTING_KEY,
                   OnRecevied = this.Receive
                });
            }
    
            private void Receive(RabbitMessageEntity messgae)
            {
                Console.WriteLine($"Pay Timeout Receive Message:{messgae.Content}");
                OrderMessage orderMessage = JsonConvert.DeserializeObject<OrderMessage>(messgae.Content);
                //获取到消息后,修改消息的状态为超时未支付 2
                orderMessage.OrderInfo.Status = 2;
                Console.WriteLine("超时未支付");
                _payService.UpdateOrderPayState(orderMessage.OrderInfo);
                messgae.Consumer.Model.BasicAck(messgae.BasicDeliver.DeliveryTag,true);
            }
    
            public Task StartAsync(CancellationToken cancellationToken)
            {
                Console.WriteLine("RabbitMQ超时支付处理程序启动");
                RabbitChannelManager channelManager = new RabbitChannelManager(_connection);
                foreach (var queueInfo in Queues)
                {
                    RabbitChannelConfig channel = channelManager.CreateReceiveChannel(queueInfo.ExchangeType,
                        queueInfo.Exchange,queueInfo.Queue,queueInfo.RoutingKey);
                    channel.OnReceivedCallback = queueInfo.OnRecevied;
                }
                return Task.CompletedTask;
            }
    
            public Task StopAsync(CancellationToken cancellationToken)
            {
                return Task.CompletedTask;
            }
        }
    }

    2.Program.cs

    using Infrastructure.Config;
    using Infrastructure.Producer;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using RabbitMQ.Services;
    using System;
    
    namespace RabbitMQ.Pay.Timeout
    {
        class Program
        {
            static void Main(string[] args)
            {
                var configRabbit = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json")
                    .Build()
                    .GetSection("RabbitMQ");
                var host = new HostBuilder()
                    .ConfigureServices(services =>
                    services.AddSingleton(new RabbitConnection(configRabbit.Get<RabbitOption>()))
                    .AddSingleton<IHostedService, ProcessPayTimeout>()
                    .AddScoped<IRabbitProducer, RabbitProducer>()
                    .AddScoped<IPayService, PayService>()).Build();
                host.Run();
            }
        }
    }

    八 运行

    1.分别使用powershell运行三个项目

    PS D:\DotNetProject\RabbitMQ.WebApiDemo\RabbitMQ.Pay> dotnet run
    PS D:\DotNetProject\RabbitMQ.WebApiDemo\RabbitMQ.Pay.Timeout> dotnet run
    PS D:\DotNetProject\RabbitMQ.WebApiDemo\RabbitMQ.WebApi.Order> dotnet run

    2.使用浏览器打开http://localhost:5000/swagger/index.html

      

    3.模拟正常支付

     

     4.模拟超时支付

    首先执行3步骤,发送请求

    然后powershell控制台不做任何操作 

    执行结果如下:

    5.模拟支付失败

    支付金额不够 

    先发送请求,然后请输入的金额输入一个不是100的值 

    执行结果:

  • 相关阅读:
    对于glut和freeglut的一点比较和在VS2013上的配置问题
    应用程序无法启动(0*c000007b)
    无法定位程序输入点glPopAttrib于动态连结库OPENGL.dll上
    计算机中丢失OPENGL.dll
    Visual Studio "无法查找或打开PDB文件"解决方法
    VC包含目录、附加依赖项、库目录及具体设置
    无法解析的外部符号 _WinMain@16
    OpenGL入门学习
    linux-用户建立及权限分配
    linux下添加用户并赋予root权限
  • 原文地址:https://www.cnblogs.com/hobelee/p/15781524.html
Copyright © 2011-2022 走看看