How do I publish to only a certain subscriber ServiceModelEx?

232 Views Asked by At

Ok so I am changing the way that my service pushes out notifications to clients. Right now the way that ServiceModelEx is working is that if any client is subscribed to an event it messages all subscribed users regardless if the message is for them. At the client I determine whether or not the message is for them. As you can imagine that can generate a lot of network traffic especially when you only need to send to certain clients.

Right now I am using TransientSubscriptions.

I tried debugging the code but the only thing I can tell is that each subscriber is stored as some type of Generic CallbackChannel.

Each TransientSubscriber is defined this way.

T subscriber = OperationContext.Current.GetCallbackChannel<T>();

When it adds a TransientSubscriber it executes this.

static void AddTransient(T subscriber, string eventOperation) {
    lock (typeof(SubscriptionManager<T>)) {
        List<T> list = m_TransientStore[eventOperation];
        if (list.Contains(subscriber)) {
            return;
        }
        list.Add(subscriber);
    }
}

If there is a better way then I am open to suggestions. I just want to send a notification to 1 client instead of all clients.

Also here is an msdn article on ServiceModelEx.

2

There are 2 best solutions below

1
On BEST ANSWER

Ok so here is what I did. I added another generic class but this one holds a userID and the Generic CallbackChannel.

public class Subscriber<T> {
    private int _UserID;
    private T _Subscription;

    public int UserID {
        get { return _UserID; }
        set { _UserID = value; }
    }
    public T Subscription {
        get { return _Subscription; }
        set { _Subscription = value; }
    }
}

I then switched every parameter in ServiceModelEx that held T to hold Subscriber<T>. After that I created a new FireEvent called FireUserEvent that then passes the UserID down through the GetTransientList methods, which I also created new ones for to pass in the UserID. That way it only returns the Subscriber<T> for said User.

0
On

You don't (Juval explicitly recommends that you don't do this). The entire purpose of pub/sub is that events go to all subscribers. You should never be filtering who gets them. They are utilities with no business logic in them. Once you start adding filtering you risk descending down a rabbit hole of coupling volatile business logic into your utility.

If there are clients that should get certain events why are they subscribed to them? Maybe you're bundling too many event types into the one pub/sub contract. You can solve this by splitting up your events into multiple contracts, although when using the ServiceModelEx pub/sub this will require you to use multiple pub/sub services. You can solve this by creating a message routing pub/sub using Action="*" as per this example: http://blogs.microsoft.co.il/sasha/2008/03/15/wcf-router-and-publishsubscribe-sample-implementation/

Alternately if you want to provide an event back to a specific caller you should be using a different mechanism. E.g. ServiceModelEx also provides something called the response service, search for "response service" at: http://idesign.net/downloads.