• [转载]「服务」WCF中NetNamedPipeBinding的应用实例


    「服务」WCF中NetNamedPipeBinding的应用实例

    WCF中有很多种绑定,根据官方的说法,NetNamedPipeBinding是适用于同一台主机中不同进程之间的通信的。

    今天终于实现了一个简单实例,整理一下。

    1、服务端创建

    首先要说一下,WCF服务是需要宿主程序的,可以寄宿在windows服务中、控制台中、桌面程序中……

    看很多教程都是创建一个WCF项目,然后在创建一个其他项目去引用,实际摸索了一下,发现完全不用,直接在其他项目中去写相关代码即可。

    依照个人喜好,我选择直接创建控制台项目。

    例如:创建控制台项目【ConsolePipeWcf1】,添加【ConsoleServer1.cs】类 用于代码的方式配置服务,新建一个【Server1】的文件夹用于添加服务的接口和类:

    1.  
      ConsolePipeWcf1 ┳
    2.  
      ┣Program.cs --程序主入口
    3.  
      ┣ConsoleServer1.cs --用于配置服务
    4.  
      ┗┳Server1
    5.  
      ┣Server1.cs --接口的实现
    6.  
      ┗IServer1.cs --接口的定义

    首先,实现服务的主要内容

    接口【IServer1.cs】:

    1.  
      using System.ServiceModel;
    2.  
       
    3.  
      namespace ConsolePipeWcf1.Server1
    4.  
      {
    5.  
      [ServiceContract]
    6.  
      interface IServer1
    7.  
      {
    8.  
      [OperationContract]
    9.  
      string GetData(int value);
    10.  
      }
    11.  
      }

    【Server1.cs】:

    1.  
      using System.Collections.Generic;
    2.  
      using System.ServiceModel;
    3.  
       
    4.  
      namespace ConsolePipeWcf1.Server1
    5.  
      {
    6.  
      class Server1 : IServer1
    7.  
      {
    8.  
      public string GetData(int value)
    9.  
      {
    10.  
      //内容就敷衍一下吧
    11.  
      return string.Format("2 * value = {0}", 2 * value);
    12.  
      }
    13.  
      }
    14.  
      }

    配置服务【ConsoleServer1.cs】:

    (里面有些大括号只是为了代码好理解和方便查看加的)

    1.  
      using System;
    2.  
      using System.ServiceModel;
    3.  
      using ConsolePipeWcf1.Server1;
    4.  
      using System.ServiceModel.Description;
    5.  
       
    6.  
      namespace ConsolePipeWcf1
    7.  
      {
    8.  
      //创建一个服务类
    9.  
      class ConsoleServer1
    10.  
      {
    11.  
      //基地址
    12.  
      private Uri baseAddress;
    13.  
      //终结点地址
    14.  
      public string address;
    15.  
      //服务主机实例
    16.  
      public ServiceHost serviceHost;
    17.  
       
    18.  
      public ConsoleServer1()
    19.  
      {
    20.  
      baseAddress = new Uri("http://localhost:8010/console/server1/");
    21.  
      address = "net.pipe://localhost/console/server1/";
    22.  
      serviceHost = new ServiceHost(typeof(Server1.Server1), baseAddress);
    23.  
      }
    24.  
       
    25.  
      public void CreatServer()
    26.  
      {
    27.  
      //NetNamedPipeBinding实例与配置
    28.  
      NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);
    29.  
      {
    30.  
      binding.CloseTimeout = new TimeSpan(0, 1, 0);
    31.  
      binding.OpenTimeout = new TimeSpan(0, 1, 0);
    32.  
      binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
    33.  
      binding.SendTimeout = new TimeSpan(0, 1, 0);
    34.  
      binding.TransactionFlow = false;
    35.  
      binding.TransferMode = TransferMode.Buffered;
    36.  
      binding.TransactionProtocol = TransactionProtocol.OleTransactions;
    37.  
      binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
    38.  
      binding.MaxBufferPoolSize = 424288;
    39.  
      binding.MaxBufferSize = 65536;
    40.  
      binding.MaxConnections = 10;
    41.  
      binding.MaxReceivedMessageSize = 65536;
    42.  
      }
    43.  
      //Set Behavior
    44.  
      {
    45.  
      ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    46.  
      smb.HttpGetEnabled = false;
    47.  
      smb.HttpsGetEnabled = false;
    48.  
      serviceHost.Description.Behaviors.Add(smb);
    49.  
      }
    50.  
      //Add Endpoint
    51.  
      {
    52.  
      //添加 mex终结点
    53.  
      serviceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
    54.  
      MetadataExchangeBindings.CreateMexHttpBinding(),
    55.  
      "mex");
    56.  
      //添加NetNamedPipeBinding的终结点
    57.  
      serviceHost.AddServiceEndpoint(typeof(IServer1), binding, address);
    58.  
      }
    59.  
      }
    60.  
       
    61.  
      //打开服务
    62.  
      public void OpenServer()
    63.  
      {
    64.  
      serviceHost.Open();
    65.  
      Console.WriteLine("The service1 is ready.");
    66.  
      }
    67.  
       
    68.  
      //关闭服务
    69.  
      public void CloseServer()
    70.  
      {
    71.  
      serviceHost.Close();
    72.  
      Console.WriteLine("The service1 is closed.");
    73.  
      }
    74.  
      }
    75.  
      }

    当然,以上代码也可以通过【App.Config】来实现,由于我的是控制台项目,默认的配置文件过于简单,可以新建个WCF项目把配置文件复制过来再改比较方便:

    详见注释:

    1.  
      <?xml version="1.0" encoding="utf-8" ?>
    2.  
      <configuration>
    3.  
      <appSettings>省略</appSettings>
    4.  
      <system.web>省略</system.web>
    5.  
      <system.serviceModel>
    6.  
      <services>
    7.  
      <service name="ConsolePipeWcf1.Server1.Server1"><!--服务名要对!-->
    8.  
      <host>
    9.  
      <!--要有基地址-->
    10.  
      <baseAddresses>
    11.  
      <add baseAddress="http://localhost:8010/console/server1/" />
    12.  
      </baseAddresses>
    13.  
      </host>
    14.  
      <!--添加netNamedPipeBinding终结点-->
    15.  
      <endpoint address="net.pipe://localhost/console/server1/"
    16.  
      binding="netNamedPipeBinding"
    17.  
      contract="WCFNetNamedDemo.INnService">
    18.  
      </endpoint>
    19.  
      <!--mex终结点-->
    20.  
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    21.  
      </service>
    22.  
      </services>
    23.  
      <bindings>
    24.  
      <!--netNamedPipeBinding终结点设置-->
    25.  
      <netNamedPipeBinding>
    26.  
      <binding closeTimeout="00:01:00"
    27.  
      openTimeout="00:01:00"
    28.  
      receiveTimeout="00:10:00"
    29.  
      sendTimeout="00:01:00"
    30.  
      transactionFlow="false"
    31.  
      transferMode="Buffered"
    32.  
      transactionProtocol="OleTransactions"
    33.  
      hostNameComparisonMode="StrongWildcard"
    34.  
      maxBufferPoolSize="524288"
    35.  
      maxBufferSize="65536"
    36.  
      maxConnections="10"
    37.  
      maxReceivedMessageSize="65536">
    38.  
      <security mode="Transport">
    39.  
      <transport protectionLevel="EncryptAndSign" />
    40.  
      </security>
    41.  
      </binding>
    42.  
      </netNamedPipeBinding>
    43.  
      </bindings>
    44.  
      <behaviors>
    45.  
      <serviceBehaviors>
    46.  
      <behavior>
    47.  
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
    48.  
      </behavior>
    49.  
      </serviceBehaviors>
    50.  
      </behaviors>
    51.  
      </system.serviceModel>
    52.  
      </configuration>

    最后就是宿主程序,也就是我的控制台主程序【Program.cs】:

    1.  
      using System;
    2.  
       
    3.  
      namespace ConsolePipeWcf1
    4.  
      {
    5.  
      class Program
    6.  
      {
    7.  
      static void Main(string[] args)
    8.  
      {
    9.  
      //创建服务
    10.  
      ConsoleServer1 server1 = new ConsoleServer1();
    11.  
      server1.CreatServer();
    12.  
      //到开服务
    13.  
      server1.OpenServer();
    14.  
      //随便输入什么就关闭
    15.  
      Console.ReadLine();
    16.  
      server1.CloseServer();
    17.  
      }
    18.  
      }
    19.  
      }

    完成以上,服务端就算完成。

    2、客户端调用

    新建控制台项目【ConsoleServer1Client】

    把服务端的【IServer1.cs】接口文件(协议)复制过来,添加到项目中

    然后:

    1.  
      using System;
    2.  
      //添加必要的引用
    3.  
      using System.ServiceModel;
    4.  
      //服务端IServer1的命名空间(由直接复制过来的IServer1.cs文件决定的)
    5.  
      using ConsolePipeWcf1.Server1;
    6.  
       
    7.  
      namespace ConsoleServer1Client
    8.  
      {
    9.  
      class Program
    10.  
      {
    11.  
      static void Main(string[] args)
    12.  
      {
    13.  
      var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);
    14.  
      var address = new EndpointAddress("net.pipe://localhost/console/server1/");
    15.  
      //创建通道
    16.  
      var factory = new ChannelFactory<IServer1>(binding, address);
    17.  
      IServer1 channel = factory.CreateChannel();
    18.  
      //调用(因为有IServer1.cs文件,所以智能提示能提示出接口中的方法,不会报错)
    19.  
      string s = channel.GetData(5);//随便给个数
    20.  
      Console.WriteLine(s);
    21.  
      Console.ReadKey();
    22.  
      }
    23.  
      }
    24.  
      }

    运行:

    完成!

    原文地址: https://blog.csdn.net/Raink_LH/article/details/103721408

    最后,如果用App.Config文件配置的话就不需要 CreatServer 这个方法了,

    这种情况启动服务如下(因为配置server,endpoint 等信息已在App.Config文件):

    static void Main(string[] args)
    {
    ServiceHost serviceHost = new ServiceHost(typeof(Services.CalculatorService));
    //到开服务
    serviceHost.Open();
    Console.WriteLine("server start.......");
    //随便输入什么就关闭
    Console.ReadLine();
    serviceHost.Close();

    }

  • 相关阅读:
    设计模式之里氏替换原则
    设计模式之依赖倒置原则讲解
    条款10 若不想使用编译器自动生成的函数,就该明确拒绝
    Django---常用字段和参数
    Python中abc
    Python中鸭子类型
    Python多继承的正确打开方式:mixins机制
    python新式类和经典类的区别
    Django---drf权限、频率、过滤、排序、异常处理
    删库跑路技巧 删库跑路命令
  • 原文地址:https://www.cnblogs.com/wgscd/p/13439952.html
Copyright © 2020-2023  润新知