如何创建WCF回调c#

时间:2018-02-03 12:49:59

标签: c# wcf callback

我正在尝试创建一个接受接口的wcf服务,并在客户端调用其他wcf函数时激活它。 Wcf服务接口:

  [ServiceContract]
        public interface IAction
        {
            [OperationContract]
            void OnIndexChanged(int index);
        }

        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
        [ServiceContract]
        public interface IService1
        {

            [OperationContract]
            void Add(int iCount);

            [OperationContract]
            void Subtract(int iCount);

            [OperationContract]
            void Subscribe(IAction action);
            // TODO: Add your service operations here
        }

WCF服务实施:

 public class Service1 : IService1
    {
        static int index = 0;
        static IAction act = null;

        public void Add(int iCount)
        {
            index += iCount;
            act?.OnIndexChanged(index);
        }

        public void Subscribe(IAction action)
        {
            act = action;
        }

        public void Subtract(int iCount)
        {
            index -= iCount;
            act?.OnIndexChanged(index);
        }
    }

客户:

 public class TestAction : IAction
    {
        public int Index { get; set; }

        public void Run()
        {
            Index = 0;

            WCF.IService1 service = new WCF.Service1Client();
            try
            {
                service.Subscribe(this);
                service.Add(3);
                service.Subtract(2);
                service.Add(1);
            }
           catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        public void OnIndexChanged(int index)
        {
            Index = index;
            Console.WriteLine("On_Changed_Index is - > " + index);
        }
    }

主要:

 class Program
    {
        static void Main(string[] args)
        {

            TestAction ts = new TestAction();
            ts.Run();

            Console.Read();
        }
    }

然而它不起作用。它表示存在类型序列化异常,如下所示:

 There was an error while trying to serialize parameter http://tempuri.org/:action. The InnerException message was 'Type 'Tester.TestAction' with data contract name 'TestAction:http://schemas.datacontract.org/2004/07/Tester' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.'.  Please see InnerException for more details.

有谁知道为什么会这样?我不想给出一个特定的名称,因为每个客户端在不同的项目中都有不同的Implemantation,所以我不能在TestAction类中指定类型的类型。

2 个答案:

答案 0 :(得分:0)

它无效。基本上,当WCF运行时接收请求时,根据SOAP中存在的Action(您从客户端调用的方法),使用反射它会创建一个服务实例,并将在该实例上调用该Action。此外,在此过程中,它将通过反序列化根据数据协定在SOAP数据包中发送的参数将参数传递给该操作。话虽如此,这意味着所有这一切都发生在不同的应用领域(事实上是过程)和通常的OOP概念实时超载,覆盖赢得了你想象的工作。在您的示例中,当您使用SOAP与另一个进程/计算机中的某些对象进行通信时,服务对TestAction一无所知。合理 ?

答案 1 :(得分:0)

您正在尝试通过事件实现回调,但WCF有一个内置方法来支持此功能。

由于 IAction 是您的回调方法,因此无需使用服务合约进行装饰。

public interface IAction
    {
    [OperationContract(IsOneWay = true)]
        void OnIndexChanged(int index);
    }

通知合同 IService1 您有回调关联。

[ServiceContract(CallbackContract = typeof(IAction))]    [服务合约]     公共接口IService1     {

    [OperationContract]
    void Add(int iCount);

    [OperationContract]
    void Subtract(int iCount);

    }

现在您可以决定何时调用您的回调方法。

public void Add(int iCount)
        {
       index += iCount;                
OperationContext.Current.GetCallbackChannel<IAction>().OnIndexChanged(index);
        }

同样对于减法方法也是如此。

现在,如果你想调用回调,你需要通过在主类的方法中实现来调用回调的接口方法。

 [CallbackBehavior(UseSynchronizationContext = false)]


 class MyClass:FullNameSpace.IAction 
    {
       public void MainMethod()
       {
       InstanceContext instanceContext = new InstanceContext(this);
         mynamespace.Service1 client = new
          //your add and subtract method can be accessed by client.
       }
        public void OnIndexChanged(int index)
        {
           string result= = index.ToString() ;      
        }
    }