天天看点

WCF初探 --- 多个契约、多个服务 绑定一个端口

目的:

在1个wcf 服务应用程序中,包含多个服务契约 IService1.cs  IService2.cs ....等。在winform窗体作为宿主,启动wcf,并绑定 IService1.cs  IService2.cs 到同一个端口5031下面。

 步骤

1、正常创建wcf 应用程序,然后添加wcf 服务,这时包含2个契约。

WCF初探 --- 多个契约、多个服务 绑定一个端口

2、添加一个winform项目,并引用-添加服务引用,发现上述wcf服务。这是涉及到wcf的启动方式了,有程序设置、配置文件配置2种启动方式。

方法1、配置文件方式 ,修改 winform项目-app.config如下:

要注意 :

        <baseAddresses>

                 <!--<add baseAddress="http://10.76.37.152:5031/"/>-->

                  <!--如果是绑定多个服务到1个端口,这里不写地址,在程序中指定-->

          </baseAddresses>

如果是启动1个服务绑定到1个端口,上面的baseAddress要留下,如果是绑定多个服务到1个端口,如本文,则此处注释掉,在程序中指明,如下:

private void btnStart_Click(object sender, EventArgs e)
        {
            host1 = new ServiceHost(typeof(CCWorkbench.Server.Service1), new Uri("http://10.76.37.152:5031/ser1"));
            host1.Open();

            host2 = new ServiceHost(typeof(CCWorkbench.Server.Service2), new Uri("http://10.76.37.152:5031/ser2"));
            host2.Open();

            //this.ServiceStart();
            this.label1.Text = "服务启动成功!";
        }
           

配置文件如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
  
  <system.serviceModel>
    <services>
      
      
      <!--Service1 的启动-->
      <service name="CCWorkbench.Server.Service1" behaviorConfiguration="behavior">
        <host>
          <baseAddresses>
            <!--<add baseAddress="http://10.76.37.152:5031/"/>-->
            <!--如果是绑定多个服务到1个端口,这里不写地址,在程序中指定-->
          </baseAddresses>
        </host>
        <endpoint address=""   binding="wsHttpBinding" contract="CCWorkbench.Server.IService1"></endpoint>
      </service>
    
     <!--Service2 的启动-->
      <service name="CCWorkbench.Server.Service2" behaviorConfiguration="behavior">
        <host>
          <baseAddresses>
            <!--<add baseAddress="http://10.76.37.152:5031/"/>-->
            <!--如果是绑定多个服务到1个端口,这里不写地址,在程序中指定-->
          </baseAddresses>
        </host>
        <endpoint address=""   binding="wsHttpBinding" contract="CCWorkbench.Server.IService2"></endpoint>
      </service>
    
       </services>
    
      
    <behaviors>
      <serviceBehaviors>
        <behavior name="behavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
 
  </system.serviceModel>
</configuration>
           

此时,启动宿主,开启服务,可以在 http://10.76.37.152:5031/ser1  访问 Service1 服务,在http://10.76.37.152:5031/ser2  访问Service2 服务。

WCF初探 --- 多个契约、多个服务 绑定一个端口

方法2、程序设置启动多个服务

首先,winform的配置文件中不要增加内容,保持app.config默认的状态,

程序中 如下:我觉得关键是   ServiceHost serviceHost = new ServiceHost(item.Value, new Uri(endpointAddress)); 这句话中的 new Uri(endpointAddress) ,指定了地址。

private List<ServiceHost> serviceHosts = new List<ServiceHost>();
        private void ServiceStart()
        {
            if (serviceHosts != null)
            {
                foreach (ServiceHost t in serviceHosts)
                {
                    if (t != null)
                        t.Close();
                }
            }
            else
            {
                serviceHosts = new List<ServiceHost>();
            }

            string serviceAddress = string.Format("http://{0}:{1}", "10.76.37.152", "5031");
            Dictionary<Type, Type> sevtypes = new Dictionary<Type, Type>();

            sevtypes.Add(typeof(CCWorkbench.Server.IService1), typeof(CCWorkbench.Server.Service1));
            sevtypes.Add(typeof(CCWorkbench.Server.IService2), typeof(CCWorkbench.Server.Service2));

            string endpointAddress = string.Empty;
            string tName = string.Empty;
            StringBuilder msgService = new StringBuilder();
            foreach (var item in sevtypes)
            {
                tName = item.Key.Name.Substring(1);
                endpointAddress = serviceAddress + tName;
                if (!serviceAddress.EndsWith("/"))
                    endpointAddress = string.Format("{0}/{1}", serviceAddress, tName);
                //下面这句重要,设定了URL地址。是关键。
                ServiceHost serviceHost = new ServiceHost(item.Value, new Uri(endpointAddress));
                //加载元数据结点

                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                serviceHost.Description.Behaviors.Add(smb);
                serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

                WSHttpBinding wsb = new WSHttpBinding();
                wsb.Security.Mode = SecurityMode.None;
                serviceHost.AddServiceEndpoint(item.Key, wsb, endpointAddress);

                //加载NetTcpBinding结点
                //NetTcpBinding netTcpBinding = new NetTcpBinding();
                //netTcpBinding.Security.Mode = SecurityMode.None;
                //netTcpBinding.ReceiveTimeout = TimeSpan.Parse("00:10:00");
                //netTcpBinding.MaxBufferPoolSize = 2147483647;
                //netTcpBinding.MaxBufferSize = 2147483647;
                //netTcpBinding.MaxConnections = 10;
                //netTcpBinding.ReaderQuotas.MaxDepth = 2147483647;
                //netTcpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
                //netTcpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
                //netTcpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
                //netTcpBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
                //netTcpBinding.MaxReceivedMessageSize = 2147483647;
                //serviceHost.AddServiceEndpoint(item.Key, netTcpBinding, endpointAddress);


                serviceHost.Opened += delegate
                {
                    msgService.AppendLine(string.Format("{0}开始监听 Uri 为 :{1}/mex", tName, endpointAddress.ToString()));
                };
                serviceHost.Open();
                serviceHosts.Add(serviceHost);
            }
        }
           

方法3:后来测试发现的,其实如方法1,只要在baseAddress的最后,增加别名就可以绑定2个服务到1个端口,配置文件关键部分如下: <add baseAddress="http://10.76.37.152:5031/ser1"/>    <add baseAddress="http://10.76.37.152:5031/ser2"/> 是重点,增加了ser1  ser2  ,

程序中和启动单个服务的写法一样,就可以绑定2个服务到1个端口。

private void btnStart_Click(object sender, EventArgs e)
        {
            //host1 = new ServiceHost(typeof(CCWorkbench.Server.Service1), new Uri("http://10.76.37.152:5031/ser1"));
            host1 = new ServiceHost(typeof(CCWorkbench.Server.Service1));
            host1.Open();

            //host2 = new ServiceHost(typeof(CCWorkbench.Server.Service2), new Uri("http://10.76.37.152:5031/ser2"));
            host2 = new ServiceHost(typeof(CCWorkbench.Server.Service2));
            host2.Open();

            //this.ServiceStart();
            this.label1.Text = "服务启动成功!";
        }
           
<!--Service1 的启动-->
      <service name="CCWorkbench.Server.Service1" behaviorConfiguration="behavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://10.76.37.152:5031/ser1"/>
            <!--如果是绑定多个服务到1个端口,这里不写地址,在程序中指定-->
          </baseAddresses>
        </host>
        <endpoint address=""   binding="wsHttpBinding" contract="CCWorkbench.Server.IService1"></endpoint>
      </service>
    
     <!--Service2 的启动-->
      <service name="CCWorkbench.Server.Service2" behaviorConfiguration="behavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://10.76.37.152:5031/ser2"/>
            <!--如果是绑定多个服务到1个端口,这里不写地址,在程序中指定-->
          </baseAddresses>
        </host>
        <endpoint address=""   binding="wsHttpBinding" contract="CCWorkbench.Server.IService2"></endpoint>
      </service>
           

完成,效果如方法1.

初学,有很多地方也不明白。

参考文章:https://www.cnblogs.com/luomingui/archive/2012/09/06/2674220.html