WCF深入浅出学习1

1、本文主要对WCF的基本使用做简单化介绍,对于初学WCF的来说,初期对于配置文件的理解,比较烦躁吧,相信你看完了该文,能够达到深入浅出的感觉。

关于WCF的概念 和 应用场景,在此处不做详细介绍,可用参考如下博主的首页:

http://www.cnblogs.com/artech/archive/2007/02/26/656901.html

2、好了,开始创建我们的WCF类库、宿主、和测试项目吧。

首先,先看一下我的解决方案:

(1)、先创建一个WCF服务库

(2)添加新项,FirstService,这个是我自己新建的。

(3)系统会自动给我们创建了上面两个类,一个接口,一个实现:

对接口定义操作方法(这里的申明都不需要public等限定符):

    public interface IFirstService
    {
        [OperationContract]
        void DoWork();

        [OperationContract]
        string HelloWorld(string name);
    }

(4)、实现部分

    public class FirstService : IFirstService
    {
        public void DoWork()
        {
            Console.WriteLine("This is the method DoWork.");
        }

        public string HelloWorld(string name)
        {
            return "Hello" + name;
        }

    }

(5)由于我们创建了两个服务,所以系统会给我们自动生产他们的配置文件,在这里(我们对其只需了解,因为我们并没有使用它,

因为我们是将WCF类库寄宿于Console应用上,我们的配置文件并不是这个,但和这个很多是相同的)

上图,对我们的两个服务进行了ABC的配置。我们可用将该类库设置为启动项直接运行,如下图,那么他就读取了该配置文件了。

请记住这个地址,会和我寄宿的地址不同。上面的也可以在VS提供的界面进行测试WCF服务。


 

接下来,我们将上面的库寄宿到控制台应用上。

创建控制台应用程序WCF1HOST,添加对 System.ServiceModel 和 上面 类库dll的引用;

代码如下:

class Program    {
        static void Main(string[] args)
        {
            try
            {
                ServiceHost host1 = new ServiceHost(typeof(WCF1.Service1));
                host1.Open();
                Console.WriteLine("Service1 服务已经开启。");

                ServiceHost host2 = new ServiceHost(typeof(WCF1.FirstService));
                host2.Open();
                Console.WriteLine("FirstService 服务已经开启。");

                Console.WriteLine("输入exit可关闭服务并退出");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            while (true)
            {
                string input = Console.ReadLine();
                if (input.Equals("exit"))
                {
                    break;
                }
                Console.WriteLine("服务继续...");
            }
            
            
            //单个服务
            //using (ServiceHost host = new ServiceHost(typeof(WCF1.FirstService)))
            //{
            //    try
            //    {
            //        host.Open();
            //        Console.WriteLine("FirstService 服务已经开启。");
            //        Console.ReadLine();
            //    }
            //    catch (Exception ex)
            //    {
            //        Console.WriteLine(ex.Message);
            //    }
                
            //}

            ////创建宿主的基地址,假如我们没有配置 App.config 那么我们就需要指定了。
            //Uri baseAddress = new Uri("http://localhost:8080/FirstService");
            ////创建宿主
            //using (ServiceHost host = new ServiceHost(typeof(WCF1.FirstService), baseAddress))
            //{
            //    //向宿主中添加终结点
            //    host.AddServiceEndpoint(typeof(WCF1.FirstService), new WSHttpBinding(), "");
            //    //将HttpGetEnabled属性设置为true
            //    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            //    smb.HttpGetEnabled = true;
            //    //将行为添加到Behaviors中
            //    host.Description.Behaviors.Add(smb);
            //    //打开宿主
            //    host.Open();
            //    Console.WriteLine("WCF中的HTTP监听已启动....");
            //    Console.ReadLine();
            //    host.Close();
            //}
        }
    }

对于上面的注视部分,相信大家也很容易理解,这里给出了两种(一种读取配置文件、一种手动配置URI,我们建议配置URI)

我们查看App.config文件(如果没有就创建)

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

  <system.serviceModel>

    <!--Bindings-->
    <bindings>
      <netHttpBinding>
        <binding name="IFirstServiceBinding"/>
      </netHttpBinding>
    </bindings>
    
    <!--Behavior-->
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <!--Services-->
    <services>
      <service name="WCF1.Service1">
        <endpoint address="http://localhost:8888/Service1" binding="basicHttpBinding" contract="WCF1.IService1">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8888/Service1" />
          </baseAddresses>
        </host>
      </service>
      
      <!--第二个Service-->
      <service name="WCF1.FirstService">
        <endpoint address="http://localhost:8888/FirstService" binding="basicHttpBinding" contract="WCF1.IFirstService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8888/FirstService" />
          </baseAddresses>
        </host>
      </service>
      
    </services>
    <!--结束多个Service-->
    
    
  </system.serviceModel>

</configuration>

可用看到:<services> 就是我们的服务,我们这里提供了两个服务,此处

baseAddress="http://localhost:8888/Service1 和我们的类库中的地址已经不同了。 
但是配置确是相同的,都是配置ABC,这里的配置也是基本的标准配置。开启我们的寄宿程序如下:



最后,我们在客户端程序上测试,添加对两个服务的引用,如下

客户端调用服务引用,和调用类是一样的原理
class Program
    {
        static void Main(string[] args)
        {
       //创建服务类 WCFTest1.MyService1.Service1Client sev1
= new MyService1.Service1Client(); Console.WriteLine("调用:Service1.GetData Method: " + sev1.GetData(3)); WCFTest1.MyFirstService.FirstServiceClient firstSev = new MyFirstService.FirstServiceClient(); Console.WriteLine("调用:Service1.MyFirstService Method: " + firstSev.HelloWorld("weiyaowen")); Console.WriteLine("调用:Service1.HelloWorldAsync Method: " + firstSev.HelloWorldAsync("weiyaowen").Result); //获取异步调用WCF的 Result Console.ReadLine(); } }
查看客户端下的配置文件App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IFirstService" />
                <binding name="BasicHttpBinding_IService1" />
            </basicHttpBinding>
        </bindings>
        <client>
          <!--以下是配置两个服务的地址,在我们添加了服务引用之后会自动添加-->
            <endpoint address="http://localhost:8888/FirstService" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IFirstService" contract="MyFirstService.IFirstService"
                name="BasicHttpBinding_IFirstService" />
          <!--IService1-->
            <endpoint address="http://localhost:8888/Service1" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService1" contract="MyService1.IService1"
                name="BasicHttpBinding_IService1" />
        </client>
    </system.serviceModel>
</configuration>

上面的文件在添加了服务引用之后会自动生成,可用看到,和我们寄宿服务的地址一模一样的,这样我们的客户端就能够顺利的找到WCF服务的地址了。

查看结果:




另外:在看看创建类库自动生产的配置,下面飘红的字体很明确的说了:主机的需要另外配置,那么我们可用选择拷贝过去咯,改下地址就OK了:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- 部署服务库项目时,必须将配置文件的内容添加到 
  主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
  <system.serviceModel>
    <services>
      <service name="WCF1.Service1">
        <endpoint address="" binding="basicHttpBinding" contract="WCF1.IService1">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733//WCF1/Service1/" />
          </baseAddresses>
        </host>
      </service>
      <service name="WCF1.FirstService">
        <endpoint address="" binding="basicHttpBinding" contract="WCF1.IFirstService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733//WCF1/FirstService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- 为避免泄漏元数据信息,
          请在部署前将以下值设置为 false -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- 要接收故障异常详细信息以进行调试,
          请将以下值设置为 true。在部署前设置为 false 
            以避免泄漏异常信息-->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

我们完全可用在创建寄宿应用程序时,将该文件,只修改一下BaseAddress 就能够部署:如下测试。

 


分享共进步!

 

posted @ 2016-04-21 11:29  艾野草  阅读(506)  评论(0编辑  收藏  举报