• WCF callback机制的应用:实时投票模型


    在WCF应用callback模式时,一些指导性的document给出的建议是将callback contract内的operation的Message Exchange Pattern设置为IsOneWay.

    当然,当service调用callback而不需要从client instance获得callback的return value的时候,MEP设置为IsOneWay不失为最好的选择了。但是如果在某些应用场景下,我们需要获得客户端callback结果时候,就不能将MEP设置为IsOneWay=true了。

    当然,当MEP设置为IsOneWay=false的时候,其他同步设置必须相应match,即ConcurrentMode只能为ReEntrant或者Multiple。

    下面给出一个简单的应用模式:在线实时投票。

    其简单系统模型如下:

    WCF service提供一个简单的投票服务,收集投票结果通过callback机制得到各个client的结果后然后返回给service,然后WCF service给出statistics.

     针对这样的投票模型,在设置service的时候需要注意的是:

    1.callback contract中的operation一定要设置为IsOneWay=false。否则callback无法return至服务端

    2.ConcurrentMode不能设置为Single,而只能为ReEntrant或者Multiple.

    3. 当service callbacks client的时候,callback result的处理权在service,比如对结果进行统计处理等等。

    下面给出主要的source code:

    callback contract和service contract的定义

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;

    namespace WCFCallBack
    {
        [ServiceContract]
        
    public interface ICaculatorCallBack
        {
            [OperationContract]
            
    int Equals(int result);
        }

        [ServiceContract(CallbackContract
    =typeof(ICaculatorCallBack))]   
        
    public interface ICaculatorService
        {
            [OperationContract]
            
    void AddTo(int n);

            [OperationContract]
            
    void Register();
        }
    }

    servicecontract implementation以及消息发布

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;

    namespace WCFCallBack
    {
        
    public class AddEventAgrs : EventArgs
        {
           
    public int result;
        }

        [ServiceBehavior(ConcurrencyMode
    =ConcurrencyMode.Reentrant)]
        
    class CaculatorService:ICaculatorService
        {
            
    public delegate void AddEventHandler(object sender, AddEventAgrs e);
            
    public static event AddEventHandler OnAddCompleted;
            
    public ICaculatorCallBack callback;
            
    public int result;

            
    public CaculatorService()
            {
                result 
    = 0;
                Console.WriteLine(
    "A Calculator Instance is constructed");
            }

            
    public void Register()
            {
                callback 
    = System.ServiceModel.OperationContext.Current.GetCallbackChannel<ICaculatorCallBack>();
                OnAddCompleted 
    += new AddEventHandler(CaculatorService_OnAddCompleted);
            }


            
    void CaculatorService_OnAddCompleted(object sender, AddEventAgrs e)
            {
                Console.WriteLine(
    "the OnAdd event has been triggered");
                Console.WriteLine(
    "the callback result from client is "+callback.Equals(e.result));

            }

            
    public void BroadAddEvent(AddEventAgrs e, AddEventHandler temp)
            {
                
    if (OnAddCompleted != null)
                {
                    
    foreach (AddEventHandler handler in temp.GetInvocationList())
                    {
                        handler.BeginInvoke(
    this, e, nullnull);
                    }
                }
            }
           
            
    public void AddTo(int n)
            {
                AddEventAgrs e 
    = new AddEventAgrs();
                
    this.result += n;
                e.result 
    = result;
                BroadAddEvent(e, OnAddCompleted);
            }
        }
    }

    client1 callback实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace WCFClient
    {
        
    class CallBack:ICaculatorServiceCallback
        {
            
    public int Equals(int n)
            {
                
    //Console.WriteLine("haha");
                Console.WriteLine("this callback is implemented on client,the callback result is {0}", n.ToString());
                
    return 2*n ;
            }
        }
    }

    client2 callback implementation

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace WCFClient
    {
        
    class CallBack:ICaculatorServiceCallback
        {
            
    public int Equals(int n)
            {
                Console.WriteLine(
    "I have received a broadcasting news,the callback result is {0}", n.ToString());
                System.Threading.Thread.Sleep(
    2000);
                
    return n * n;
            }
        }
    }

    运行结果:

    service screenshot

    client1 screenshot

    client 2 screenshot

  • 相关阅读:
    Discuz X 2.5 点点(伪静态)
    jq 、xml 省市级联动
    php memcache 初级使用(2)
    关于windows虚拟内存管理的页目录自映射
    SharePoint 2010 网络上的开发经验和资源
    SharePoint 2010 Reporting Services 报表服务器正在内置 NT AUTHORITY\SYSTEM 账户下运行 解决方法
    SharePoint 2010 Reporting Services 报表服务器无法解密用于访问报表服务器数据库中的敏感数据或加密数据的对称密钥 解决方法
    Active Directory Rights Management Services (AD RMS)无法检索证书层次结构。 解决方法
    SharePoint 2010 Reporting Services 报表服务器实例没有正确配置 解决方法
    SharePoint 2010 页面引用 Reporting Services 展现 List 报表
  • 原文地址:https://www.cnblogs.com/Winston/p/1345647.html
Copyright © 2020-2023  润新知