提供跨服务调用的订阅者列表 [英] Making a list of subscribers available across calls to a service

查看:22
本文介绍了提供跨服务调用的订阅者列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我创建了一个有回调的服务.类似于this.它工作得很好,但我想做的是让任何已订阅的客户端被通知该服务已被调用(并将一些数据传递给回调函数),但这并不像我想象的那么容易.

So I have created a service that has a callback. Something like this. It works well enough but what I would like to do is have any client that has subscribed be notified that the service was called (and pass some data to the callback function) however this isn't as easy as I thought.

我创建了两个客户端,一个调用服务,一个监听,但是虽然我可以看到侦听器"(客户端一)订阅,但在随后(从客户端二)调用服务时,订阅者列表是空的(除了调用服务,它也订阅).我启动的第一个客户不在订阅者列表中.我尝试了一些技巧来解决这个问题,但都失败了.本质上,我尝试的是创建一个静态类,该类保留一个静态订阅者列表.

I created two clients, one to call the service and one to listen but although I can see the "listener" (client one) subscribe, on the subsequent call to the service (from client two) the list of subscribers is empty (well except for the calling service, which also subscribes). The first client I started isn't in the list of subscribers. I tried a few tricks to solve this and all of them have failed. Essentially what I tried was a hack to create a static class that kept a static list of subscribers.

几个值得注意的要求.这必须是一个 http 绑定,所以我使用的是 WSDualHttpBinding,我还使用了安全令牌,因此协议是 SOAP.我想知道在设置端点时是否可以执行某些操作?好像那可能是个好地方?我不确定.

a couple of noteworthy requirements. This has to be an http binding so I am using WSDualHttpBinding, I am also using security tokens so the protocol is SOAP. I am wondering if there is something I can do when I set up the endpoint? It seems like that might be a good place? I am not sure though.

那么,如何获取订阅者列表,以便在调用我的服务时访问任何订阅的客户端?我猜有一个很好的方法可以做到这一点,希望有人能指出我正确的方向.

So, how do I get a list of subscribers such that I can access any of the subscribed clients whenever my service is called? I am guessing there is a good way to do this hopefully someone can point me in the right direction.

谢谢

推荐答案

我只能说我做了什么(我不知道它是否是一种好的风格:)但它有效).

i just can say what i have done (i dont know if it is a good style:) but it works).

我用 InstanceContextMode.Single 创建了一个服务

i create a service with InstanceContextMode.Single

 [ServiceBehavior(
    InstanceContextMode = InstanceContextMode.Single,
    ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service : IService
{}

我使用一个简单的字典来保存我的客户端连接",其中键是客户端ID".

i use a simple dictionary to hold my client "connections" in which the key is the client "ID".

private static Dictionary<GUID, IAdvServiceCallback> Subscribers;

我定义了订阅和取消订阅方法

i define a subscribe and unsubscribe methode

    public bool Subscribe(GUID key)
    {
        try
        {
            if (Subscribers == null)
            {
                Subscribers = new Dictionary<GUID, IAdvServiceCallback>();
            }

            lock (Subscribers)
            {
                IServiceCallback callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();

                if (!Subscribers.ContainsKey(key))
                {
                    Subscribers.Add(key,callback);
                    ICommunicationObject obj = (ICommunicationObject)callback;
                    obj.Closed += SubscribedServiceClosed;
                    obj.Faulted += SubscribedServiceFaulted;
                }
                else
                {
                    //log subscriber is registered
                }
            }
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }


    public bool UnSubscribe()
    {
        try
        {
            if (Subscribers == null)
            {
                return true;
            }

            lock (Subscribers)
            {
                IServiceCallback callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();
                if (Subscribers.ContainsValue(callback))
                {
                    var row = Subscribers.Where(v => v.Value == callback).FirstOrDefault();

                    Subscribers.Remove(row.Key);
                }    
            }
            return true;
        }
        catch(Exception ex)
        {
            return false;
        }
    }

现在该服务可以向所有订阅者发送消息

and now the service can send messages to all subscribers

Subscribers.Values.ToList().ForEach(delegate(IServiceCallback callback)
            {
                if (((ICommunicationObject) callback).State == CommunicationState.Opened)
                {
                   //send callback
                }
                else
                {
                   // remove subscriber because channel its not open anymore
                }
             });

这篇关于提供跨服务调用的订阅者列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆