WCF 学习笔记之双工实现

 

WCF 学习笔记之双工实现

其中 Client 和Service为控制台程序 Service.Interface为类库

首先了解契约Interface两个接口

using System.ServiceModel;

using System.ServiceModel.Channels;

namespace Artech.WcfServices.Service.Interface

{

    [ServiceContract(Namespace = "http://www.artech.com/", CallbackContract = typeof(ICalculatorCallback))]

    public interface ICalculator

    {

        [OperationContract(IsOneWay = true)]

        void Add(double x, double y);

    }

}

这边要注意两个地方:一个是明确回调查的接口,和设置让它为单向模式[CallbackContract = typeof(ICalculatorCallback)];IsOneWay = true

回调接口的代码如下:     

using System.ServiceModel;

namespace Artech.WcfServices.Service.Interface

{

    public interface ICalculatorCallback

    {

        [OperationContract(IsOneWay = true)]

        void DisplayResult(double result, double x, double y);

    }

}

此处也有两个地方要注意:回调契约没有定义[ServiceContact]的特性是因为在指定CallbackContract属性时就隐含对应的接口是个服务契约;此外同样也要设置为单向IsOneWay = true

接下来是服务实现层的代码:

using System.ServiceModel;

using Artech.WcfServices.Service.Interface;

using System.Threading;

namespace Artech.WcfServices.Service

{

    public class CalculatorService : ICalculator

    {

        public void Add(double x, double y)

        {

            double result = x + y;

            ICalculatorCallback callback = OperationContext.Current.GetCallbackChannel<ICalculatorCallback>();

            callback.DisplayResult(result, x, y);

        }

    }

}

相对应的App.config配置

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>    

    <behaviors>

      <serviceBehaviors>

        <behavior name="exposeExceptionDetail">

          <serviceDebug includeExceptionDetailInFaults="true"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <services>

      <service name="Artech.WcfServices.Service.CalculatorService"

               behaviorConfiguration="exposeExceptionDetail">

        <endpoint address="net.tcp://127.0.0.1:3721/calculatorservice"

                  binding="netTcpBinding"

                  contract="Artech.WcfServices.Service.Interface.ICalculator"/>

      </service>

    </services>

  </system.serviceModel>

</configuration>

关于绑定类型的选择必须明确是支持双向通信的类型才可以;比如NetTcpBinding,WSDualHttpBinding ;这边应该注意在采用WSDualHttpBinding时要把可靠会话打开,因为它是通过可靠会话维护两个HTTP通道之间的匹配;
例如:<reliableSession enabled="true"/>

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>

    <bindings>

      <netTcpBinding>

        <binding name="reliableSessionBinding">

          <reliableSession enabled="true"/>

        </binding>

      </netTcpBinding>

    </bindings>

    <behaviors>

      <serviceBehaviors>

        <behavior name="exposeExceptionDetail">

          <serviceDebug includeExceptionDetailInFaults="true"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <services>

      <service name="Artech.WcfServices.Service.CalculatorService"

               behaviorConfiguration="exposeExceptionDetail">

        <endpoint address="net.tcp://127.0.0.1:3721/calculatorservice"

                  binding="netTcpBinding"

                  bindingConfiguration="reliableSessionBinding"

                  contract="Artech.WcfServices.Service.Interface.ICalculator"/>

      </service>

    </services>

  </system.serviceModel>

</configuration>

服务层还有一个代码就是宿主打开

using System.ServiceModel;

using Artech.WcfServices.Service.Interface;

using System.Threading;

using System.ServiceModel.Description;

namespace Artech.WcfServices.Service

{

    class Program

    {

        static void Main(string[] args)

        {

            using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))

            {

                host.Open();

                Console.Read();

            }

        }

    }

}

接下来是客户端的实现,要实现回调接口的

using Artech.WcfServices.Service.Interface;

namespace Artech.WcfServices.Client

{

    public class CalculatorCallbackService : ICalculatorCallback

    {

        public void DisplayResult(double result, double x, double y)

        {

            Console.WriteLine("x + y = {2} when x = {0}  and y = {1}", x, y, result);

        }

    }

}

以及相对应的配置文件内容:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>    

    <client>

      <endpoint name ="calculatorservice"

                address="net.tcp://127.0.0.1:3721/calculatorservice"

                binding="netTcpBinding"

                contract="Artech.WcfServices.Service.Interface.ICalculator"/>

    </client>

  </system.serviceModel>

</configuration>


以及运行的代码:

using System.ServiceModel;

using Artech.WcfServices.Service.Interface;

using System.ServiceModel.Channels;

using System.Threading;

namespace Artech.WcfServices.Client

{

    class Program

    {

        static void Main(string[] args)

        {

            InstanceContext callback = new InstanceContext(new CalculatorCallbackService());

            using (DuplexChannelFactory<ICalculator> channelFactory = new DuplexChannelFactory<ICalculator>(callback, "calculatorservice"))

            {

                ICalculator calculator = channelFactory.CreateChannel();

                calculator.Add(1, 2);

            }

            Console.Read();

        }

    }

}


针对TCP协议要把服务器的相对应服务打开;或者可能会报错;

WCF 学习笔记之双工实现

错误一:TransportManager 无法使用 NetTcpPortSharing 服务侦听提供的 URI: 无法启动服务,因为该服务已禁用。管理员运行 "sc.exe config NetTcpPortSharing start= demand" 可以将其启用 [NetTcpPortSharing 服务没有启动]

错误二:TransportManager 无法使用 NetTcpPortSharing 服务侦听提供的 URI: 服务侦听失败 [端口被占用,换个端口]

你可能感兴趣的:(学习笔记)