using System;
|
using System.Collections.Generic;
|
using System.Threading.Tasks;
|
|
namespace Bro.Common.PubSub
|
{
|
/// <summary>
|
/// 简单发布/订阅中心
|
/// </summary>
|
public class SimplePubSubCenter : IPubSubCenter
|
{
|
/// <summary>
|
/// 订阅主题和订阅者
|
/// </summary>
|
private readonly Dictionary<string, Subscribers> subMap = new Dictionary<string, Subscribers>();
|
|
/// <summary>
|
/// 订阅事件
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <param name="method"></param>
|
/// <returns></returns>
|
public bool Subscribe(string tag, Func<ISubscriber, object, object, object> method)
|
{
|
var sub = new SimpleSubscriber();
|
|
// 默认使用hash值设置名称,防止重复
|
sub.SubscriberName = sub.GetHashCode().ToString();
|
sub.SubMethod = method;
|
|
return Subscribe(tag, sub);
|
}
|
|
/// <summary>
|
/// 订阅事件
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <param name="subscribe"></param>
|
/// <returns></returns>
|
public bool Subscribe(string tag, ISubscriber subscribe)
|
{
|
if (null == tag || null == subscribe)
|
{
|
return false;
|
}
|
|
if (subMap.ContainsKey(tag))
|
{
|
var subs = subMap[tag];
|
|
return subs.Add(subscribe);
|
}
|
else
|
{
|
var subs = new Subscribers();
|
if (!subs.Add(subscribe))
|
{
|
return false;
|
}
|
|
subMap.Add(tag, subs);
|
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// 发布事件
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <param name="data"></param>
|
/// <param name="isAsync">是否异步,true:异步 false:同步</param>
|
public void Publish(string tag, object param1, object param2, bool isAsync = false)
|
{
|
if (null == tag)
|
{
|
return;
|
}
|
|
// 获取所有tag订阅者
|
var subs = GetSubscribers(tag);
|
if (null == subs)
|
{
|
return;
|
}
|
|
var enmtor = subs.GetEnumerator();
|
if (null == enmtor)
|
{
|
return;
|
}
|
|
// 通知所有订阅者事件
|
while (enmtor.MoveNext())
|
{
|
var cur = enmtor.Current;
|
if (null == cur || null == cur.SubMethod)
|
{
|
continue;
|
}
|
|
if (!isAsync)
|
{
|
cur.SubMethod(cur, param1, param2);
|
}
|
else
|
{
|
//cur.SubMethod.BeginInvoke(cur, param1, param2, null, null);
|
|
Task.Run(() =>
|
{
|
cur.SubMethod(cur, param1, param2);
|
});
|
}
|
}
|
}
|
|
/// <summary>
|
/// 获取所有订阅者
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <returns></returns>
|
public Subscribers GetSubscribers(string tag)
|
{
|
if (!subMap.ContainsKey(tag))
|
{
|
return null;
|
}
|
|
return subMap[tag];
|
}
|
|
/// <summary>
|
/// 获取某个订阅者
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <param name="name"></param>
|
/// <returns></returns>
|
public ISubscriber GetSubscriber(string tag, string name)
|
{
|
var subs = GetSubscribers(tag);
|
if (null == subs)
|
{
|
return null;
|
}
|
|
return subs.GetSubscriber(name);
|
}
|
|
/// <summary>
|
/// 移除某个订阅者
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <param name="name"></param>
|
/// <returns></returns>
|
public bool RemoveSubscriber(string tag, string name)
|
{
|
var subs = GetSubscribers(tag);
|
if (null == subs)
|
{
|
return false;
|
}
|
|
if (!subs.Rmv(name))
|
{
|
return false;
|
}
|
|
if (subs.GetCount() == 0)
|
{
|
subMap.Remove(tag);
|
}
|
|
return true;
|
}
|
|
/// <summary>
|
/// 移除订阅
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <param name="method"></param>
|
/// <returns></returns>
|
public bool RemoveSubscriber(string tag, Func<ISubscriber, object, object, object> method)
|
{
|
var subs = GetSubscribers(tag);
|
if (null == subs)
|
{
|
return false;
|
}
|
|
if (!subs.Rmv(method))
|
{
|
return false;
|
}
|
|
if (subs.GetCount() == 0)
|
{
|
subMap.Remove(tag);
|
}
|
|
return true;
|
}
|
|
/// <summary>
|
/// 移除某类所有订阅者
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <returns></returns>
|
public bool RemoveSubscribers(string tag)
|
{
|
var subs = GetSubscribers(tag);
|
if (null == subs)
|
{
|
return false;
|
}
|
|
subMap.Remove(tag);
|
|
return true;
|
}
|
|
//IEnumerable<Object> Publish(string tag, object data);
|
|
//IEnumerable<Object> Publish(string tag);
|
|
//IEnumerable<Object> Publish(IPublisher publisher);
|
}
|
|
/// <summary>
|
/// 订阅者集合
|
/// </summary>
|
public class Subscribers
|
{
|
/// <summary>
|
/// 订阅者集合
|
/// </summary>
|
private readonly Dictionary<string, ISubscriber> subMap = new Dictionary<string, ISubscriber>();
|
|
/// <summary>
|
/// 订阅者集合
|
/// </summary>
|
private readonly List<ISubscriber> subList = new List<ISubscriber>();
|
|
public Subscribers()
|
{
|
|
}
|
|
/// <summary>
|
/// 新增订阅者
|
/// </summary>
|
/// <param name="sub"></param>
|
/// <returns></returns>
|
public bool Add(ISubscriber sub)
|
{
|
if (null == sub || subMap.ContainsKey(sub.SubscriberName))
|
{
|
return false;
|
}
|
|
subMap.Add(sub.SubscriberName, sub);
|
subList.Add(sub);
|
|
return true;
|
}
|
|
/// <summary>
|
/// 移除订阅者
|
/// </summary>
|
/// <param name="sub"></param>
|
/// <returns></returns>
|
public bool Rmv(ISubscriber sub)
|
{
|
if (null == sub || !subMap.ContainsKey(sub.SubscriberName))
|
{
|
return false;
|
}
|
|
subMap.Remove(sub.SubscriberName);
|
subList.Remove(sub);
|
|
return true;
|
}
|
|
/// <summary>
|
/// 移除订阅者
|
/// </summary>
|
/// <param name="name"></param>
|
/// <returns></returns>
|
public bool Rmv(string name)
|
{
|
if (!subMap.ContainsKey(name))
|
{
|
return false;
|
}
|
|
var sub = subMap[name];
|
|
subMap.Remove(name);
|
subList.Remove(sub);
|
|
return true;
|
}
|
|
/// <summary>
|
/// 移除订阅者
|
/// </summary>
|
/// <param name="method"></param>
|
/// <returns></returns>
|
public bool Rmv(Func<ISubscriber, object, object, object> method)
|
{
|
var names = new List<string>();
|
|
try
|
{
|
foreach (var item in subMap)
|
{
|
if (null == item.Value)
|
{
|
continue;
|
}
|
|
// 若是相同函数,则移除
|
if (item.Value.SubMethod == method)
|
{
|
names.Add(item.Key);
|
}
|
}
|
|
for (int i = 0; i < names.Count; i++)
|
{
|
subMap.Remove(names[i]);
|
}
|
|
names.Clear();
|
|
return true;
|
}
|
catch (Exception ex)
|
{
|
}
|
|
return false;
|
}
|
|
/// <summary>
|
/// 检察订阅者是否存在
|
/// </summary>
|
/// <param name="sub"></param>
|
/// <returns></returns>
|
public bool Contains(ISubscriber sub)
|
{
|
if (null == sub || !subMap.ContainsKey(sub.SubscriberName))
|
{
|
return false;
|
}
|
|
return true;
|
}
|
|
/// <summary>
|
/// 获取订阅者
|
/// </summary>
|
/// <param name="name"></param>
|
/// <returns></returns>
|
public ISubscriber GetSubscriber(string name)
|
{
|
if (!subMap.ContainsKey(name))
|
{
|
return null;
|
}
|
|
return subMap[name];
|
}
|
|
/// <summary>
|
/// 清除所有订阅者
|
/// </summary>
|
public void Clear()
|
{
|
subMap.Clear();
|
subList.Clear();
|
}
|
|
/// <summary>
|
/// 获取订阅者枚举
|
/// </summary>
|
/// <returns></returns>
|
public IEnumerator<ISubscriber> GetEnumerator()
|
{
|
return subList.GetEnumerator();
|
}
|
|
/// <summary>
|
/// 获取订阅者数量
|
/// </summary>
|
/// <returns></returns>
|
public int GetCount()
|
{
|
return subMap.Count;
|
}
|
}
|
}
|