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

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

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

1、服务端创建

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

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

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

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

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

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

接口【IServer1.cs】:

using System.ServiceModel;

namespace ConsolePipeWcf1.Server1
{
    [ServiceContract]
    interface IServer1
    {
        [OperationContract]
        string GetData(int value);
    }
}

【Server1.cs】:

using System.Collections.Generic;
using System.ServiceModel;

namespace ConsolePipeWcf1.Server1
{
    class Server1 : IServer1
    {
        public string GetData(int value)
        {
            //内容就敷衍一下吧
            return string.Format("2 * value = {0}", 2 * value);
        }
    }
}

配置服务【ConsoleServer1.cs】:

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

using System;
using System.ServiceModel;
using ConsolePipeWcf1.Server1;
using System.ServiceModel.Description;

namespace ConsolePipeWcf1
{
    //创建一个服务类
    class ConsoleServer1
    {
        //基地址
        private Uri baseAddress;
        //终结点地址
        public string address;
        //服务主机实例
        public ServiceHost serviceHost;  

        public ConsoleServer1()
        {
            baseAddress = new Uri("http://localhost:8010/console/server1/");
            address = "net.pipe://localhost/console/server1/";
            serviceHost = new ServiceHost(typeof(Server1.Server1), baseAddress);
        }

        public void CreatServer()
        {
            //NetNamedPipeBinding实例与配置
            NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);
            {
                binding.CloseTimeout = new TimeSpan(0, 1, 0);
                binding.OpenTimeout = new TimeSpan(0, 1, 0);
                binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
                binding.SendTimeout = new TimeSpan(0, 1, 0);
                binding.TransactionFlow = false;
                binding.TransferMode = TransferMode.Buffered;
                binding.TransactionProtocol = TransactionProtocol.OleTransactions;
                binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
                binding.MaxBufferPoolSize = 424288;
                binding.MaxBufferSize = 65536;
                binding.MaxConnections = 10;
                binding.MaxReceivedMessageSize = 65536;
            }
            //Set Behavior
            {
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = false;
                smb.HttpsGetEnabled = false;
                serviceHost.Description.Behaviors.Add(smb);
            }
            //Add Endpoint
            {
                //添加 mex终结点
                serviceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                               MetadataExchangeBindings.CreateMexHttpBinding(),
                                               "mex");
                //添加NetNamedPipeBinding的终结点
                serviceHost.AddServiceEndpoint(typeof(IServer1), binding, address);                
            }
        }

        //打开服务
        public void OpenServer()
        {
            serviceHost.Open();
            Console.WriteLine("The service1 is ready.");            
        }

        //关闭服务
        public void CloseServer()
        {
            serviceHost.Close();
            Console.WriteLine("The service1 is closed.");
        }
    }
}

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

详见注释:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>省略</appSettings>
  <system.web>省略</system.web>
  <system.serviceModel>
    <services>
      <service name="ConsolePipeWcf1.Server1.Server1"><!--服务名要对!-->
        <host>
          <!--要有基地址-->
          <baseAddresses>
            <add baseAddress="http://localhost:8010/console/server1/" />
          </baseAddresses>
        </host>  
        <!--添加netNamedPipeBinding终结点-->      
        <endpoint address="net.pipe://localhost/console/server1/" 
                  binding="netNamedPipeBinding" 
                  contract="WCFNetNamedDemo.INnService">
        </endpoint>
        <!--mex终结点-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />       
      </service>
    </services>
    <bindings>
      <!--netNamedPipeBinding终结点设置-->
      <netNamedPipeBinding>
        <binding closeTimeout="00:01:00"
                 openTimeout="00:01:00"
                 receiveTimeout="00:10:00"
                 sendTimeout="00:01:00"
                 transactionFlow="false"
                 transferMode="Buffered"
                 transactionProtocol="OleTransactions"
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferPoolSize="524288"
                 maxBufferSize="65536"
                 maxConnections="10"
                 maxReceivedMessageSize="65536">
          <security mode="Transport">
            <transport protectionLevel="EncryptAndSign" />
          </security>
        </binding>
      </netNamedPipeBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

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

using System;

namespace ConsolePipeWcf1
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建服务
            ConsoleServer1 server1 = new ConsoleServer1();
            server1.CreatServer();
            //到开服务
            server1.OpenServer();
            //随便输入什么就关闭
            Console.ReadLine();
            server1.CloseServer();
        }
    }
}

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

2、客户端调用

新建控制台项目【ConsoleServer1Client】

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

然后:

using System;
//添加必要的引用
using System.ServiceModel;
//服务端IServer1的命名空间(由直接复制过来的IServer1.cs文件决定的)
using ConsolePipeWcf1.Server1;

namespace ConsoleServer1Client
{
    class Program
    {
        static void Main(string[] args)
        {
            var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);
            var address = new EndpointAddress("net.pipe://localhost/console/server1/");
            //创建通道
            var factory = new ChannelFactory<IServer1>(binding, address);
            IServer1 channel = factory.CreateChannel();
            //调用(因为有IServer1.cs文件,所以智能提示能提示出接口中的方法,不会报错)
            string s = channel.GetData(5);//随便给个数
            Console.WriteLine(s);
            Console.ReadKey();
        }
    }
}

运行:

完成!

有点长了,下次说关于回调的实现,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值