WCF 服务如何向其客户端引发事件?

Posted

技术标签:

【中文标题】WCF 服务如何向其客户端引发事件?【英文标题】:How can a WCF Service Raise Events to its Clients? 【发布时间】: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(); 

【问题讨论】:

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

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

【讨论】:

我怎样才能达到我帖子中提到的要求。 @John : 任何链接或代码。 实际上,确实如此,而且您对您的帮助非常无益。其他答案为他们的答案提供了代码和具体说明,而您只是提供居高临下的 cmets。

以上是关于WCF 服务如何向其客户端引发事件?的主要内容,如果未能解决你的问题,请参考以下文章

有没有一种简单的方法来模拟 WCF 服务和 WCF 客户端之间的事件?

从第三方 WCF 获取底层异常 - SOAP 异常

服务器已拒绝客户端凭据,WCF 作为 Windows 服务

在域帐户下运行的 WCF 服务

客户端 Blazor 代码能否“听到”服务器端引发的事件?

当客户端连接到 WCF 托管的端点时触发事件