我正在设计我的所有客户都将连接到的 2 个 WCF 服务。其中一项服务将是通知服务。
我希望每个客户端都连接到服务,订阅它,然后使用双工回调接口(interface)接收通知(服务将触发客户端中的“通知”操作)。
这是我的设计理念:
我的问题是:当每个客户端连接到我的服务时,我将根据数据库中的“用户”表对其进行验证(我将使用 UserNamePasswordValidator 并实现“验证”功能)。
要求:根据数据库中定义的规则,每个用户需要接收不同的通知,但他们都使用相同的契约(Contract) .
例如:
约翰·史密斯 数据库中的规则可能是:通知我所有有价格的新产品
超过100美元。
简·多伊 数据库中的规则可能是:在所有新产品上通知我它们的名称以“JA”开头。
吉姆·贾布拉 数据库中的规则可能是:通知我所有“食品”类型的新产品。
我的服务将有一个工作线程来检测数据库中的更改(将新产品插入数据库)。
然后它应该遍历所有连接的客户端 - 并且只有当它与客户端的通知请求匹配时,才会为每个客户端向他发送新产品的通知。
再次 - 所有客户端都会收到相同类型的更新(新产品),但每个客户端应根据数据库中的规则接收不同的产品。
我认为实现这一点的一种方法是使用 单例 服务,它包含以下列表:
这样 - 每次工作线程检测到新产品时,它都会遍历此列表并将通知发送给需要它的人。
这种方法的问题在于,为了拥有一个全局客户列表 - 我需要将服务作为 Singlton,对吗?
第二种方法是......好吧......我不知道如何从工作线程访问连接到服务的客户端列表......
我想我遇到的主要问题是每个客户可能希望将不同种类的产品通知给他。含义 - pub\sub 方法在这里不太好,因为我的场景需要服务了解客户端。
关于如何解决这个头痛的任何建议?
最佳答案
无论如何,对于双工通信,您需要保持从服务器到客户端打开的 TCP channel 才能发送通知。
客户端是发起与服务器的连接的人,你需要保持这个连接打开,如果这个连接丢失,你不能(不应该)发起从服务器到客户端的连接,因为客户端可以在 NAT 之后,有防火墙,等等
因此,无论如何,服务器端必须有一些静态(单例)对象来保存客户端连接列表,认为这不一定是 WCF 服务。您可以将此对象依赖注入(inject)到服务构造函数中。
public class ProductRepository
{
private EventAggregator eventAggregator;
public void Add(Product product)
{
//...
eventAggregator.Publish(new NewProductEvent(product))
}
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class EventPublishingService
{
private IClientCallback client;
private EventAggregator eventAggregator;
private Func<Product, bool> predicate;
public EventPublishingService(...)
{
eventAggregator.Subscibe<NewProductEvent>(OnNewProduct);
}
private void OnNewProduct(NewProductEvent e)
{
if (predicate(e.Product)==true) client.Notify(e.Product);
}
public void Subscribe()
{
client = OperationContext.Current.GetCallbackChannel<IClientCallback>()
var user = ServiceSecurityContext.PrimaryIdentity;
predicate = GetFilterForUser(user);
}
}
关于WCF Duplex - 向每个客户端推送不同的通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10297892/