注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

WCF的学习总结(一)---简单的单双式通信  

2011-08-16 17:23:00|  分类: NET(C#) |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

WCF的学习总结(一)
准备在新的项目里正式应用一下WCF,这个东西毕竟是SOA的一个发展的方向,今天总结一下这两天看资料的心得。
在写了两个小工程后总结了一些小的经验,写了上来,一个工程是基于wsHttpBinding,一个工程是基于netTcpBinding,前面是单工,后面是一个双工,依靠回调来实现的。先说第一个,在wsHttpBinding绑定的形式下,明白了一个道理,WCF的布置开开发,其实相当重要的是app.config配置文件的设置,其中很多的事儿都可以通过这个配置文件来简化或者说完成。当然,微软也提供了一个工具来生成这个文件,那就是在VS2010里点击“工具”——“WCF服务配置编辑器”,然后在里面可以新建一个服务或客户端啥滴,相当滴好使,不过还是有才升到C#时的感觉,就是简单了,反而不知道怎么下手了,因为简单,到处都可以配置,反而不会配置了。
接着说事儿,不过事先声明一下,这里全部使用的自托管,或者说寄生在自己身上,而没有托管到IIS上,因为系统目前对IIS支持的不好(还得安装一些东东,暂时就不管他了,只在控制台上学习就可以了),在配置文件里,最重要的是要把你的服务接口的名称和你的配置文件内的名称相对应,在[ServiceContract]中的Name属性可以更改你发布的服务接口的名字,在实践中发现,可以使用这个属性设置的名字也可以直接使用继承这个服务接口的实体类的名字,都可以达到引用并使用的目的。
在服务端配置如下:
      <service behaviorConfiguration="meta" name="MyWCF.Services.ServicesMyCalculator">
        <endpoint address="http://127.0.0.1:9999/ServicesMyCalculator"

binding="wsHttpBinding" contract="MyWCF.Contracts.ICalculator"></endpoint>
      </service>

      <serviceBehaviors>
        <behavior name="meta">
          <serviceMetadata httpGetEnabled="true"

httpGetUrl="http://127.0.0.1:9999/ServicesMyCalculator/metadata"/>
        </behavior>
      </serviceBehaviors>

注意的是,behaviorConfiguration的值一定要和behavior的属性name设置的值一样。还有就是在httpGetUrl的字符串最后加上metadata即,“http://127.0.0.1:9999/ServicesMyCalculator/metadata”,看书上似乎有不加的,但这里必须加上,不再细究为什么,慢慢到后期可能就明白了。
同样,在客户端,你的app.config文件中:
<endpoint address="http://127.0.0.1:9999/servicesMyCalculator"

name="ServicesMyCalculator111" binding="wsHttpBinding"

contract="MyWCF.Contracts.ICalculator"></endpoint>
address,name,binding,contract的配置一定要配置准确,其中除了name可以自定义外,其它三个要和服务端的配置严格一致,否则就不能找到服务应用。
配置文件可以自己直接书写,VS2010里带有自动感知和自动提示功能,非常棒。

然后说一下服务的发布和调用的方式,WCF直接依赖于ServiceHost这个类,我们可以直接用代码动态创建这个类的实例对象,将接口寄生到这个类上,诸如这个种形式:
using (ServiceHost host = new ServiceHost(typeof(ServicesMyCalculator)))
然后使用代码动态增加它的属性,但我们上面强调了,实际的应用开发,大多还是以配置文件为主,所以才在前面讲很多项式app.config的使用方法和配置方法。这里不再详细的说明,如果大家有兴趣,可以看一下蒋金楠的BLOG,“我的WCF之旅”,

http://www.cnblogs.com/artech/archive/2007/03/02/661969.html
上面讲得非常清楚,这里只是把具体的应用时出现的问题及扩展的问题说明和解释。

客户端的调用是这样,同样,我们采用配置文件来解决动态代码增加的问题,配置好后使用的代码如下:
using (ChannelFactory<ICalculator> ChannelFactory = new ChannelFactory<ICalculator>

("ServicesMyCalculator111"))
            {
                ICalculator proxy = ChannelFactory.CreateChannel();
                using (proxy as IDisposable)
                {//使用你的接口}
             }

接下来,再说一说双向通信,基于net.tcp,这里仍然是在上一个工程上进行的修改,只是增加一个回调的过程,因此增加了一个接口
    public interface ICallback
    {
        [OperationContract(IsOneWay = true)]
        void DisplayResult(double addleft,double addright,double result);
    }
并且在上一个接口中增加了属性如下:
[ServiceContract(Name = "DuplexCalculator", Namespace = "http://www.fff.com",

CallbackContract = typeof(ICallback))]

因为这个属性的声明,我们就可以在增加的接口上不再声明其是一个服务契约了。
程序在严格按照第一个工程的配置方法的(特别是配置文件的名称的配置和地址端口一定要正确)情况下,成功运行,但这其中也出现了一个错误,“没有设置端点”这个意思,回头查找发现还是配置文件里的一些没用的文件,比如因为是从第一工程拷过来的,一些behavior属性还在,同时一些地方的绑定也因为不明白瞎改,最后把他们删去,然后改成nettcp就可以了。
然后忽然想到一个细节的问题,是不是这个东西也可以象第一个工程一样,添加服务引用,运行之,结果发现不能找到服务,很奇怪,在网上搜索,发现说这个net.tcp 是一个比较奇特的东西,得需要一些重新的配置,主要是增加元数据的访问方式,如下:
增加新端点:
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>

<serviceDebug includeExceptionDetailInFaults="False" />//这个偶工程没写
增加属性:
      <serviceBehaviors>
        <behavior name="meta">
          <serviceMetadata httpGetEnabled="false" />
        </behavior>
      </serviceBehaviors>
但是运行后仍然不正确,报“找不到具有绑定 MetadataExchangeTcpBinding 的终结点的与方案 net.tcp 匹配的基本地址 XXXXX[]”,想了半天,增加了一个基本地址,如下:
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://127.0.0.1:9999/DuplexCalculator"/>
          </baseAddresses>
        </host>
然后把net.tcp端点的地址即endpoint address=""设置成空,这时候,大家应该明白了吧,这个东西其实就是加一个前缀,来保证客户端能正确访问到地址的元数据,这时候,大家可以改回到原来,直接在
<endpoint address="mex"修改成<endpoint address="net.tcp://127.0.0.1:9999/DuplexCalculator/mex",结果发现成功。证明我们的思路的是正确的。
还有一个比较奇怪的情形,在网上搜索时,<serviceMetadata httpGetEnabled="false" />替换成<serviceMetadata httpGetEnabled="true"

httpGetUrl="http://127.0.0.1:8888/DuplexCalculator/metadata" />这个仍然可以使用,一开始把http改成了net.tcp结果报HTTP与其不匹配,改回来,增加metadata,又报端口错误,改到8888上,成功,在客户端添加服务引用,用“net.tcp://127.0.0.1:9999/DuplexCalculator/mex”(不加mex会自动增加)和“http://127.0.0.1:8888/DuplexCalculator/metadata”均可正常发现服务引用。到这里,其实所有的工作就基本完成了。
现在还有个小问题,这种通信机制,在使用ChannelFactory时,都是在本机上引用了相关的DLL,如果不是一个机器呢?
慢慢会在后面解决的,带着问题干活,进步更快,好象是这样吧。哈哈。

  评论这张
 
阅读(710)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017