zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    [LeetCode]题解(python):089-Gray Code
    [LeetCode]题解(python):088-Merge Sorted Array
    [LeetCode]题解(python):086-Partition List
    [LeetCode]题解(python):083-Remove Duplicates from Sorted List
    [LeetCode]题解(python):082-Remove Duplicates from Sorted List II
    [LeetCode]题解(python):081-Search in Rotated Sorted Array II
    [LeetCode]题解(python):080-Remove Duplicates from Sorted Array II
    [LeetCode]题解(python):079-Word Search
    [LeetCode]题解(python):078-Subsets
    软件开发冲刺5
  • 原文地址:https://www.cnblogs.com/Winston/p/1345647.html
Copyright © 2011-2022 走看看