• 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协议要把服务器的相对应服务打开;或者可能会报错;

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

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

  • 相关阅读:
    python运算符
    CocoChina开发者大会
    iphone模拟器上不能安装从itunes下载的app
    Objective-C学习--源文件结构
    Objective-C学习笔记--复合
    Objective-C学习笔记--继承
    Objective-C学习笔记--实例化对象
    Objective-C学习笔记--@implementation
    Objective-C学习笔记--@interface
    C语言函数原型
  • 原文地址:https://www.cnblogs.com/wujy/p/3172648.html
Copyright © 2020-2023  润新知