【问题标题】:How can a WCF Service Raise Events to its Clients?WCF 服务如何向其客户端引发事件?
【发布时间】:2011-08-10 00:24:23
【问题描述】:

我想知道 WCF 中是否有事件处理方式。 我在 WCF 中遇到了回调,但我想在 WCF 中进行事件处理。

我的要求就像我想向特定客户端而不是向所有使用 WCF 中的事件处理的客户端提出事件,并且我还想保持会话。

我在 WCF 中看到了处理 Callback 的 Publisher/Subscriber 模型,但是这个模型发布给所有订阅的客户端,但我只想发布给选定的客户端。

我认为这可以使用 WCF 中的事件来完成。

客户端:

public class Callbacks : IServiceCallback
{
    public void CallToMyClient(string name)
    {
        this.CallToMyClient(name);  

    }
}

protected void Page_Load(object sender, EventArgs e)
{
    Callbacks callback = new Callbacks();            
    ServiceClient client = new ServiceClient(new InstanceContext(callback));        

    client.SubscribeClient();
    client.DoSomeWork(); 
}

【问题讨论】:

    标签: wcf


    【解决方案1】:

    WCF 中没有 Event 来通知它的客户端,但是有一个回调通道,回调通道的目的与事件相同,但两者的工作原理完全不同。 要通知特定客户端,您可以做的是在订阅某处时存储该客户端的回调通道(在这种情况下,我更喜欢 Dictionary)。稍后您可以选择实例并通过该通道调用您的回调方法,这样做只会通知一个客户端。

    更新

    如果你有兴趣,这里是代码:

    public interface IClientCallback
    {
        //Your callback method
        [OperationContract(IsOneWay = true)]
        void CallToMyClient(string name);
    }
    [ServiceContract(CallbackContract = typeof(IClientCallback))]
    public interface ITestService
    {
    
        [OperationContract(IsOneWay = true)]
        void SubscribeClient();
        [OperationContract(IsOneWay = true)]
        void DoSomeWork();
    }
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class ServiceImplementation : ITestService
    {
        private static readonly List<IClientCallback> CallbackChannels = new List<IClientCallback>();
    
        /// <summary>
        /// client should call this method before being notified to some event
        /// </summary>
        public void SubscribeClient()
        {
            var channel = OperationContext.Current.GetCallbackChannel<IClientCallback>();
            if (!CallbackChannels.Contains(channel)) //if CallbackChannels not contain current one.
            {
                CallbackChannels.Add(channel);
            }
        }
    
        public void DoSomeWork()
        {
            //Here write your code to do some actual work
            //After you done with your work notify client
            //here you are calling only the first client that is registered
            IClientCallback callbackChannel = CallbackChannels[0];
            callbackChannel.CallToMyClient("You are the only one receving this message");
        }
    }
    

    【讨论】:

    • 感谢您的服务代码。我已经在上面发布了客户端代码,请看一下
    • 但我无法引发事件。
    • 我喜欢这个答案。真是太棒了。
    • This question 包含客户端代码示例。
    【解决方案2】:

    WCF Duple Operation and UI Threads By jeff.barnes

    也许这可以帮助你。

    WCF 不支持事件处理程序。回调通道是它的方式

    【讨论】:

    • 这是一个有趣的示例,易于构建和运行(只要您记得以管理员身份运行 BeerService)。我使用升级向导将其加载到 VS 2010 中(没有问题)。
    【解决方案3】:

    如果您将 WCF 用于 RPC(相对于 Web 服务或休息),您可以使用 .Net Remoting 来执行事件调用跨进程。

    【讨论】:

    • John .net 远程处理未被弃用。它的遗产并且仍然具有有价值的用例,尤其是在需要调用 RPC 事件时!请在投反对票之前进行自我教育:stackoverflow.com/questions/1294494/…
    • 请注意 MS 技术负责人自己对框架的负责任的话:“远程处理是 .Net 框架的一部分,因此它不会消失......对于进程内、跨应用程序域通信远程处理是 CLR 的原生通信方式。
    • 未命名的“MS 技术主管”的话,在某个未指定的日期,并没有改变这样一个事实,即对于几乎所有需求,WCF 都是 .NET 远程处理的替代品。即使就 OP 的请求而言,也不是需要 events - 它是 notification。 WCF 回调协定无需借助 Remoting 即可实现这一点。顺便说一句,我说的是“已弃用”,而不是“过时”。
    • 名字是 Clemens Vasters,请阅读链接中的答案
    • 我对韦斯特先生很熟悉。发表评论的日期是什么时候?有链接吗?
    【解决方案4】:

    您不能使用事件。您可以使用回调来模拟事件。

    【讨论】:

    • 我怎样才能达到我帖子中提到的要求。
    • @John : 任何链接或代码。
    • 实际上,确实如此,而且您对您的帮助非常无益。其他答案为他们的答案提供了代码和具体说明,而您只是提供居高临下的 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多