学习使用MQ+SignalR处理高并发下订单
SignalR:
创建Hubs目录
创建XXXXHub继承Hub类
// 配置即时通讯
builder.Services.AddSignalR();
// 配置允许跨域
builder.Services.AddCors(p =>
{
p.AddPolicy("Travel.Client", p =>
{
p.AllowAnyHeader();
// 这里需要改成WithOrigins()方法,填写你实际的客户端地址
p.SetIsOriginAllowed(s => true);
p.AllowAnyMethod();
p.AllowCredentials(); // 主要是为了允许signalR跨域通讯
});
});
app.UseCors("Travel.Client");
app.MapHub<TravelHub>("/Hub"); // 映射signalR通讯中心
MQ:
"Redis": "xx:6379,password=xx",
"RabbitMQ": {
"HostName": "xx",
"VirtualHost": "/",
"UserName": "admin",
"Password": "123456",
"Port": "5672"
}
var rabbitConfig = builder.Configuration.GetSection("RabbitMQ");
builder.Services.Configure<RabbitMQOptions>(rabbitConfig);
var rabbitOptions = rabbitConfig.Get<RabbitMQOptions>();
builder.Services.AddCap(p =>
{
p.UseMySql(builder.Configuration.GetConnectionString("mysql") ?? string.Empty);
p.UseEntityFramework<HappyTravelContext>();
p.UseRabbitMQ(mq =>
{
mq.HostName = rabbitOptions.HostName;
mq.VirtualHost = rabbitOptions.VirtualHost;
mq.UserName = rabbitOptions.UserName;
mq.Password = rabbitOptions.Password;
mq.Port = rabbitOptions.Port;
});
p.UseDashboard(); // 注册仪表盘
});
然后是创建了一个类存放方法名
public class EventBus
{
/// <summary>
/// 下订单
/// </summary>
public const string OrderAdd = "order.add";
}
然后是SignalR发布到控制器层//服务层也可以
await _capPublisher.PublishAsync(EventBus.OrderAdd,input);
控制器层订阅事件
[CapSubscribe(EventBus.OrderAdd,Group = EventBus.OrderAdd)]
[HttpPost]
[TravelAuthorize]
public async Task OrderAdd([FromBody]OrderAddInput input)
{
var result = await _service.OrderAdd(input);
await _Hub.Clients.Clients(input.ConnectionId).SendAsync(SignalMethod.ReceiveMessage, result);
}
流程是:
启动后端
启动前端
前端链接SignalR
// 创建连接对象
var connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:5216/Hub",{
accessTokenFactory:()=>token
}).withAutomaticReconnect() // 自动重连(0秒,2秒,10秒,30秒) 尝试四次重连
.build();
通过connection对象调用Hub里面的方法
connection.invoke("OrderAdd",addOrderBo).catch(function(err){
console.log(err);
});
Hub里OrderAdd方法发布事件
await _capPublisher.PublishAsync(EventBus.OrderAdd,input);
控制器方法订阅事件,有事件?消息后自动消费
[CapSubscribe(EventBus.OrderAdd,Group = EventBus.OrderAdd)]
流程貌似就这样