.Net Core/.Net 6/.Net 8,一个简易的消息队列
做着玩的, 只实现了消息入队出队功能,没有持久化,也没有其它任何高级功能
直接上代码
csharp
public class AMQBase//:ISingleton
{
/// <summary>
/// 主题队列
/// </summary>
public Dictionary<string,Queue<EnQueueMsg>> queues { get; set; }
/// <summary>
/// 验证用户,如果没有 IMQVerify 的实现,将不会验证用户
/// </summary>
readonly IMQVerify _verify;
public AMQBase(IMQVerify verify) {
_verify = verify;
queues = new Dictionary<string, Queue<EnQueueMsg>>();
/* 初始化时从 文件/数据库? 读取未消费消息? */
/**/
}
/// <summary>
/// 入队
/// </summary>
/// <returns></returns>
public void EnQueue(EnQueueMsg msg) {
if (_verify != null)
{
if (!_verify.Verify(msg))
{
throw new Exception("身份验证失败");
}
}
msg.msgid = Guid.NewGuid().ToString();//消息id
EnQueueAsync(msg);
}
/// <summary>
/// 异步执行入队
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task EnQueueAsync(EnQueueMsg msg)
{
//新主题
if (!queues.ContainsKey(msg.topic))
{
queues.Add(msg.topic, new Queue<EnQueueMsg>());
}
/* 异步存入文件/数据库? */
/**/
//入队
queues[msg.topic].Enqueue(msg);
}
/// <summary>
/// 出队
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public DeQueueData? DeQueue(DeQueueMsg msg)
{
if (_verify != null)
{
if (!_verify.Verify(msg))
{
throw new Exception("身份验证失败");
}
}
//没有找到主题 或者队列为空
if (!queues.ContainsKey(msg.topic))
{
return null;
}
if (queues[msg.topic].Count == 0)
{
//主题队列为空,移除主题
if (queues[msg.topic].Count == 0)
{
queues.Remove(msg.topic);
}
return null;
}
//出队
var mod=queues[msg.topic].Dequeue();
var scount = queues[msg.topic].Count;
//主题队列为空,移除主题
if (queues[msg.topic].Count == 0)
{
queues.Remove(msg.topic);
}
/* 异步 从文件/数据库 修改消息状态或删除? */
/**/
return new DeQueueData {
msgid= mod.msgid,//消息id
coutent=mod.content,//消息内容
topic= mod.topic,//主题
count= scount//剩余未消费消息数量
};
}
/// <summary>
/// 获取主题列表
/// </summary>
/// <returns></returns>
public string[] TopicList()
{
return queues.Keys.ToArray();
}
/// <summary>
/// 获取全部的主题和未消费的消息数量
/// </summary>
/// <returns></returns>
public List<MqCount> GetCount() {
return queues.Select(x=>new MqCount { topic=x.Key,count=x.Value.Count}).ToList();
}
/// <summary>
/// 获取指定的主题和未消费的消息数量
/// </summary>
/// <returns></returns>
public MqCount GetCount(string topic)
{
if (!queues.ContainsKey(topic)) return null;
return new MqCount
{
topic=topic,
count = queues[topic].Count
};
}
/// <summary>
/// 删除主题,删除整个主题队列
/// </summary>
/// <param name="topic"></param>
public async Task Remove(RemoveTopic rem)
{
if (_verify != null)
{
if (!_verify.Verify(rem))
{
throw new Exception("身份验证失败");
}
}
queues.Remove(rem.topic);
}
}
身份验证接口
csharp
/// <summary>
/// 身份验证接口
/// </summary>
public interface IMQVerify//: ISingleton
{
public bool Verify(MqMegBase mqMeg);
}
身份验证接口实现
csharp
public class AMQVerify : IMQVerify//,ISingleton
{
public bool Verify(MqMegBase mqMeg)
{
if (mqMeg.user == "mq" && mqMeg.password == "123456") return true;
return false;
}
}
program.cs
csharp
builder.Services.AddSingleton<IMQVerify, AMQVerify>();
builder.Services.AddSingleton<AMQBase>();
通过api调用
csharp
[ApiController, Route("[controller]/[action]")]
public class AMQController : Controller
{
readonly AMQBase _mq;
public AMQController(AMQBase mq)
{
_mq = mq;
}
/// <summary>
/// 入队
/// </summary>
/// <param name="msg"></param>
[HttpPost]
public async Task EnQueue(EnQueueMsg msg)
{
_mq.EnQueue(msg);
}
/// <summary>
/// 出队
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
[HttpPost]
public async Task<JsonResult> DeQueue(DeQueueMsg msg)
{
return Json(_mq.DeQueue(msg));
}
/// <summary>
/// 获取主题列表
/// </summary>
/// <returns></returns>
[HttpGet]
public JsonResult TopicList()
{
return Json(_mq.TopicList());
}
/// <summary>
/// 获取全部的主题和未消费的消息数量
/// </summary>
/// <returns></returns>
[HttpGet]
public JsonResult GetCount()
{
return Json(_mq.GetCount());
}
/// <summary>
/// 获取指定的主题和未消费的消息数量
/// </summary>
/// <param name="topic"></param>
/// <returns></returns>
[HttpGet]
public JsonResult GetTopicCount(string topic)
{
return Json(_mq.GetCount(topic));
}
/// <summary>
/// 删除主题
/// </summary>
/// <param name="rem"></param>
[HttpPost]
public void Remove(RemoveTopic rem)
{
_mq.Remove(rem);
}
}