如何创建 WCF 回调 C#



我正在尝试折痕一个 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 类中为类型指定类型。

它不起作用。基本上,当 WCF 运行时收到请求时,根据 SOAP 中存在的操作(从客户端调用的方法(,它会使用反射创建一个服务实例,并将在该实例上调用该操作。此外,在此过程中,它将通过根据数据协定反序列化在 SOAP 数据包中发送的参数来将参数传递给该操作。话虽如此,这意味着所有这些都发生在不同的应用程序域(实际上是过程(和通常的 OOP 概念实时重载中,覆盖不会像您预期的那样工作。在您的示例中,当您使用 SOAP 与另一个进程/机器中的某些对象进行通信时,服务不知道有关TestAction的任何信息。有意义?

您正在尝试通过事件实现回调,但 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() ;      
        }
    }

最新更新