加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

WCF简单教程(1) 入门

发布时间:2020-12-17 00:56:57 所属栏目:安全 来源:网络整理
导读:WCF是DotNet体系中很重要的一项技术,但是组内很多组员通过书籍自学的时候感觉涉及面太广、配置文件太复杂,新名词太多、抓不到头绪,有感于此,决定进行一次组内技术培训,顺便把培训讲义整理到blog上来。不求大而全,而是要让初学者快速入门,因此想入实例

WCF是DotNet体系中很重要的一项技术,但是组内很多组员通过书籍自学的时候感觉涉及面太广、配置文件太复杂,新名词太多、抓不到头绪,有感于此,决定进行一次组内技术培训,顺便把培训讲义整理到blog上来。不求大而全,而是要让初学者快速入门,因此想入实例入手,并刻意隐藏一些初期用不到的内容,以降低入门门槛。有任何错误欢迎指正。

注:本系列文章基于.Net Framework 3.5,以教程的最后会归纳一下到了4.0中有哪些差异。

----------------------- 分隔线 -----------------------

第一篇:入门,构建第一个WCF程序

1、服务端

建立一个控制台应用程序作为Server,新建一个接口IData作为服务契约。这个契约接口一会儿也要放到Client端,这样双方才能遵循相同的标准。别忘了添加对System.ServiceModel的引用。

  
  
  1. using?System;?
  2. using?System.ServiceModel;?
  3. using?System.Text;?
  4. ?
  5. namespace?Server?
  6. {?
  7. ????///?<summary>?
  8. ????///?用ServiceContract来标记此接口是WCF的服务契约,可以像WebService一样指定一个Namespace,如果不指定,就是默认的http://tempuri.org?
  9. ????///?</summary>?
  10. ????[ServiceContract(Namespace="WCF.Demo")]?
  11. ????public?interface?IData?
  12. ????{?
  13. ????????///?<summary>?
  14. ????????///?用OperationContract来标记此方法是操作契约?
  15. ????????///?</summary>?
  16. ????????[OperationContract]?
  17. ????????string?SayHello(string?userName);?
  18. ????}?
  19. }?


针对这个接口建立实现类,这个类才是真正干活的,工作在服务端,不出现在客户端:

  
  
  1. using?System;?
  2. using?System.Text;?
  3. ?
  4. namespace?Server?
  5. {?
  6. ????///?<summary>?
  7. ????///?实现IData接口,此处不需要写契约标记?
  8. ????///?</summary>?
  9. ????public?class?DataProvider?:?IData?
  10. ????{?
  11. ????????public?string?SayHello(string?userName)?
  12. ????????{?
  13. ????????????return?string.Format("Hello?{0}.",?userName);?
  14. ????????}?
  15. ????}?
  16. }?


为工程添加一个App.config文件,这里面要定义与服务发布相关的参数。WCF中常见的做法是用代码写服务逻辑,但是用配置文件来定义服务发布方式,这样做的好处是松散耦合。

  
  
  1. <?xml?version="1.0"?encoding="utf-8"??>?
  2. <configuration>?
  3. ??<system.serviceModel>?
  4. <!--?看到services节,就表明这是在定义服务相关的内容?-->
  5. ????<services>?
  6. ??????<!--?定义一个服务,name是契约实现类的全名?-->?
  7. ??????<service?name="Server.DataService">?
  8. ????????<!--?既然要对外提供服务,就要有服务地址,此处定义为?http://localhost:8080/wcf,需要注意,地址总是带着类型标头的?-->?
  9. ????????<host>?
  10. ???? ??<baseAddresses>?
  11. ???????? <add?baseAddress="http://localhost:8080/wcf"?/>?
  12. ????? ?</baseAddresses>?
  13. ????</host>?
  14. ???? <!--?定义一下终节点,address一般为空,如果不为空,最终服务地址就是在baseAddress的基础上加上这个address,binding指定为basicHttpBinding,这是最基础的基于http的绑定方式,contract标明这是为哪个契约服务?-->?
  15. ????<endpoint?address=""?binding="basicHttpBinding"?contract="Server.IData"?/>?
  16. ??????</service>?
  17. ????</services>?
  18. ??</system.serviceModel>?
  19. </configuration>?

?
万事具备,只剩最后一步了,将服务发布出去:

  
  
  1. using?System;?
  2. using?System.ServiceModel;?
  3. ?
  4. namespace?Server?
  5. {?
  6. ????class?Program?
  7. ????{?
  8. ????????static?void?Main(string[]?args)?
  9. ????????{?
  10. ???????? //定义一个ServiceHost,注意参数中要使用契约实现类而不是接口?
  11. ????????????using(ServiceHost?host?=?new?ServiceHost(typeof(Server.DataProvider)))?
  12. ????????????{?
  13. ????????????????host.Open();?
  14. ????????????????Console.WriteLine("Service?Running?...");?
  15. ????????????????Console.ReadKey();?
  16. ????????????????host.Close();?
  17. ????????????}?
  18. ????????}?
  19. ????}?
  20. }?

有人可能会问服务发布到哪去了?没指定地址呀?这是一个初学者容易搞不明白的地方。

是的,此时App.config中的定义就发挥作用了,由于ServiceHost中指定对Server.DataProvider类服务,而App.config中定义了name="Server.DataProvider"的service,其下有endpoint,定义了绑定方式是basicHttpBinding,而http方式的baseAddress只有一个,就是 http://localhost:8080/wcf。

编译运行,屏幕显示Service Running ... 就是正常跑起来了,此时如果用命令行 netstat -ano | findstr "8080" 看一下,应该有如下输出:

  
  
  1. TCP????0.0.0.0:8080?????????0.0.0.0:0??????????LISTENING??????4?
  2. TCP????[::]:8080????????????[::]:0?????????????LISTENING??????4?

表示我们的程序已经在TCP 8080端口开始监听了。值得注意的是PID是4,这是系统进程而不是我们自己的进程,这说明WCF程序对外提供HTTP服务时,是借用了系统功能(http.sys)。

此时如果我们用浏览器访问一下 http://localhost:8080/wcf,不报错,但是会提示“当前已禁用此服务的元数据发布”,这是由于默认不允许以http get方式获取服务的WSDL,我们不用管它,不影响后面的使用,以后的章节中我们再来看这个问题。


2、客户端

再建立一个控制台应用程序作为Client,把Server中的接口IData拷过来,因为这是服务契约。

为工程添加一个App.config文件,这里面要定义客户端访问的相关参数,这里我去掉了一些用不上的参数,以保持配置文件简单,防止各位看晕了头。

  
  
  1. <?xml?version="1.0"?encoding="utf-8"??>?
  2. <configuration>?
  3. ??<system.serviceModel>?
  4. ????<!--?看到client,就表明是客户端设置?-->?
  5. ????<client>?
  6. ??????<!--?定义访问时的终节点,name也是随意取的,注意address是Server端发布时指定的baseAddress+endpoint的address,binding也要对应,contract就更不用说了,由于之前把IData.cs拷过来的时候没有修改命名空间,所以还是Server.IData?-->?
  7. ??????<endpoint?name="DataService"?address="http://localhost:8080/wcf"?binding="basicHttpBinding"?contract="Server.IData"?/>?
  8. ????</client>?
  9. ??</system.serviceModel>?
  10. </configuration>?


然后写代码,来调用Server端发布的SayHello方法:

  
  
  1. using?System;?
  2. using?System.ServiceModel;?
  3. using?System.ServiceModel.Channels;?
  4. ?
  5. namespace?Client?
  6. {?
  7. ????class?Program?
  8. ????{?
  9. ????????static?void?Main(string[]?args)?
  10. ????????{?
  11. ????????????//客户端访问有多种方式,此处只显示一种
  12. //利用ChannelFactory的CreateChannel方法创建一个IData的代理对象,其中参数“DataService”就是刚才在App.config中定义的endpoint的名称?
  13. ????????????var?proxy?=?new?ChannelFactory<Server.IData>("DataService").CreateChannel();?
  14. ????????????//调用SayHello方法?
  15. ????????????Console.WriteLine(proxy.SayHello("WCF"));?
  16. ????????????//用完后一定要关闭,因为服务端有最大连接数,不关闭会在一定时间内一直占着有效连接?
  17. ????????????((IChannel)proxy).Close();?
  18. ????}?
  19. }?

编译运行,屏幕应能正常打印出“Hello WCF.”。第一个入门demo就搞定了,应该还是比较简单的。只是App.config的配置有些复杂,后面我们会看到,其实也可以不要配置,直接用代码搞定,不过从松散耦合的角度讲不建议这么做。

?

本文出自 “汪汪爱杨杨” 博客,请务必保留此出处http://www.voidcn.com/article/p-kfrmxoat-th.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读