本文介绍了WCF Duplex - 向每个客户端推送不同的通知?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计 2 个 WCF 服务,我的所有客户端都将连接到该服务.其中一项服务将是通知服务.

I am designing a 2 WCF services that all my clients will connect to. One of these services will be a notifications service.

我希望每个客户端都连接到该服务,订阅它,然后使用双工回调接口接收通知(该服务将在客户端中触发通知"操作).

I would like each client to connect to the service, subscribe to it and then receive notifications, using a duplex Callback interface (the service will fire the 'Notify' operation in the clients).

这是我的设计理念:

我的问题是:当每个客户端连接到我的服务时,我将根据数据库中的用户"表对其进行验证(我将使用 UserNamePasswordValidator 并实现验证"功能).

My question is: When each client connects to my service, I will validate it against the 'Users' table in my database (I will be using a UserNamePasswordValidator and implement the 'Validate' function).

要求:每个用户需要根据数据库中定义的规则接收不同的通知,但他们都使用相同的合同.

Requirement: Each user needs to receive different notifications, based on rules defined in the database, but they all use the same contract.

例如:

John Smith 在 DB 中的规则可能是:在所有有价格的新产品上通知我超过 100 美元.

John Smith's rules in the DB might be : Notify me on all new products that have a priceof over 100 dollars.

Jane Doe 在 DB 中的规则可能是:在所有新产品名称以JA"开头时通知我.

Jane Doe's rules in the DB might be : Notify me on all new products that their names begin with 'JA'.

Jim Jabra 在 DB 中的规则可能是:在所有属于食品"类型的新产品时通知我.

Jim Jabra's rules in the DB might be : Notify me on all new products that are of type 'Food'.

我的服务将有一个工作线程来检测数据库中的变化(一个新产品被插入到数据库中).

My service will have a worker thread that detects a change in the database (a new product was inserted to the database).

然后它应该遍历所有连接的客户端 - 并且对于每个客户端向他发送新产品的通知,只有当它与客户端的通知请求匹配时.

It should then loop over all the clients connected - and for each client send him a notification of the new product, only if it matches the client's notification requests.

同样 - 所有客户都会收到相同类型的更新(新产品),但每个客户应该根据数据库中的规则收到不同的产品.

Again - all clients receive the same type of update (new products), but each client should receive different products according to the rule in the database.

我认为实现这一点的一种方法是使用 Singleton 服务,该服务包含以下内容:

One approach I thought to implement this would be to use a Singleton service, that holds a list of :

  • 客户端端点
  • 用户对象(来自数据库)

这种方式 - 每次工作线程检测到新产品时,它都会遍历此列表并向需要它的人发送通知.这种方法的问题在于,为了拥有一个全球客户列表 - 我需要以 Singlton 的身份提供服务,对吗?

This way - each time the worker thread detects a new product, it loops over this list and send notifications to whome ever needs it.The problem with this approach is that in order to have one global list of clients - I need to have the service as a Singlton, right ?

第二种方法是……嗯……我不知道如何从工作线程访问连接到服务的客户端列表……

The second approach would be ... well ... I don't have another idea of how I can access a list of clients connected to the service from a worker thread ...

我想我遇到的主要问题是每个客户可能希望向他通知不同类型的产品.意思是 - pubsub 方法在这里不太好,因为我的场景需要服务了解客户端.

I guess the main problem I have is that each client might want different kinds of product notified to him. Meaning - the pubsub method is not so good here, because my scenario requires the service to know about the clients.

关于如何解决这个令人头疼的问题有什么建议吗?

Any suggestions on how I can solve this headaches ?

推荐答案

在任何双工通信中,您都需要保持从服务器到客户端打开的 TCP 通道才能发送通知.

In any way with duplex communication, you need to maintain TCP channel opened from server to client to be able to send notification.

客户端是发起连接到服务器的人,你需要保持这个连接打开,如果这个连接丢失,你不能(不应该)发起从服务器到客户端的连接,因为客户端可以在 NAT 之后,有防火墙等.

Client is the one who initiate connection to server, and you need to keep this connection open, if this connection is lost you can't (shouldn't) initiate connection from server to client, because client can be behind NAT, have firewall, etc.

所以无论如何,服务器端必须有一些静态(单例)对象来保存客户端连接列表,认为这不一定是 WCF 服务.您可以将此对象依赖注入到服务构造函数中.

So in any way there must be some static (singleton) object on server side that keeps clients connections list, thought this is not necessarily WCF service. You can dependency inject this object into service constructor.

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 - 向每个客户端推送不同的通知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 08:56