[Solution] 一步一步WCF(1) 快速入门
Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台。整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并融合有HTTP和FTP的相关技术。是Windows平台上开发分布式应用最佳的实践方式。
安装:在.net framework 3.0的时候已经内置了WCF。
由于WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主。在本节将介绍2种服务寄宿服务,并分别通过Code和Config的方式为WCF服务绑定endpoint:
1.建立项目
- Service:一个控制台应用,实现对wcf服务的寄宿,该项目引用System.ServiceMode程序集。(WCF框架的绝大部分实现和API定义在该程序集中)
- Client:一个控制台应用,实现对服务的调用端,该项目引用System.ServiceMode程序集。(生成的代理类继承自该程序集)
2.创建契约(contract)
WCF包含四种类型的契约:服务契约、数据契约、消息契约和错误契约。这里所指服务契约,用来声明服务的所有操作。
要使一个接口成为一个契约,需要为其贴上特性标签。
1 2 3 4 5 6 7 8 9 10 11 | using System.ServiceModel; namespace Service { [ServiceContract] public interface ICar { [OperationContract] string Run( int distance); } } |
3.实现服务
实现接口方法即可
1 2 3 4 5 6 7 8 9 10 | namespace Service { public class CarService : ICar { public string Run( int distance) { return "行驶了" + distance; } } } |
4.开始寄宿
WCF采用终结点的通信方式。终结点包括Address,Binding,Contract,简称ABC。
Address: 指定wcf的location
Binging: 指定传输协议。(tcp http msmq等)
Contract: 指定服务的Behavior。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.ServiceModel; namespace Service { class Program { static void Main( string [] args) { using ( var host = new ServiceHost( typeof (CarService))) { //指定服务的终结点,分别指定Contract,Binding,Address host.AddServiceEndpoint( typeof (ICar), new BasicHttpBinding(), "http://localhost:10000/Car" ); host.Open(); Console.WriteLine( "服务启动成功" ); Console.Read(); } } } } |
(已管理员身份启动Service.exe)
服务以及寄宿成功,那我们怎么调用呢。实际上,这样的方式是无法被调用的。客户端引用的地址是服务的元数据。所以我们需要把服务的元数据暴露出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using System; using System.ServiceModel; using System.ServiceModel.Description; namespace Service { class Program { static void Main( string [] args) { using ( var host = new ServiceHost( typeof (CarService))) { if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null ) { //服务的元数据 允许Get方式从下面的Url中获取 var behavior = new ServiceMetadataBehavior { HttpGetEnabled = true , HttpGetUrl = new Uri( "http://localhost:10000/Car/Metadata" ) }; host.Description.Behaviors.Add(behavior); } //指定服务的终结点,分别指定Contract,Binding,Address host.AddServiceEndpoint( typeof (ICar), new BasicHttpBinding(), "http://localhost:10000/Car" ); host.Opened += (o, e) => Console.WriteLine( "服务启动成功" ); host.Open(); Console.Read(); } } } } |
5.服务的调用
服务的调用有2种方式,VS引用服务生成代理类,Code自定义代理类(需要保证Endpoint完全一致)。
Code自定义代理类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.ServiceModel; namespace Client { class Program { static void Main( string [] args) { //一致的终结点 using ( var channelFactory = new ChannelFactory<ICar>( new BasicHttpBinding(), "http://localhost:10000/Car" )) { //手动创建代理类 var proxy = channelFactory.CreateChannel(); Console.WriteLine(proxy.Run(3)); } Console.Read(); } } } |
这里面的ICar(Contract),并非一定和wcf服务的ICar完全一致(指命名空间,所在程序集名称),只需方法签名一致即可。(由于是Contract仍需对应的特性)
1 2 3 4 5 6 7 8 9 10 11 | using System.ServiceModel; namespace Client { [ServiceContract] interface ICar { [OperationContract] string Run( int distance); } } |
在管理员运行前面的Service.exe基础上,运行Client.exe。
1.建立项目
2.文件结构
3.svc文件
svc文件相当于asmx文件,通过一个必须指令Service,指定具体的服务。如Service="WcfService.Service1"
在vs中,浏览器查看svc文件,svc的地址就是服务的地址。svc的地址+?wsdl是服务描述的地址。
4.服务的调用
和自我寄宿的服务类似,只用将Address改成svc的地址即可。
注意,在新建svc文件的时候,vs会自动修改Web.config文件。(用来指定服务的元数据暴露行为)
1 2 3 4 5 6 7 8 9 | < system.serviceModel > < behaviors > < serviceBehaviors > < behavior name="">//指定默认的behavior < serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> </ behavior > </ serviceBehaviors > </ behaviors > </ system.serviceModel > |
以上基本均采用Code的方式实现WCF,实际上WCF非常灵活,一般都采用Config方式。或者Config+Code(都会生效)。
wcf的配置涉及到2种,服务的发布,服务的调用。
发布:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | < system.serviceModel > < behaviors > < serviceBehaviors > < behavior name="meta"> < serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:10001/Car/Metadata"/> </ behavior > </ serviceBehaviors > </ behaviors > < services > < service name="Service.CarService" behaviorConfiguration="meta"> < endpoint address="http://localhost:10001/Car" binding="wsHttpBinding" contract="Service.ICar"></ endpoint > < endpoint address="http://localhost:10001/Car2" binding="wsHttpBinding" contract="Service.ICar"></ endpoint > </ service > </ services > </ system.serviceModel > |
调用:
1 2 3 4 5 | < system.serviceModel > < client > < endpoint name="car" address="http://localhost:10001/Car" binding="wsHttpBinding" contract="Client.ICar"></ endpoint > </ client > </ system.serviceModel > |
当调用端采用配置方式的时候,代码改成如下方式调用。(配置中name用来区分不同的endpoint,代码中也使用对应的name创建信道栈Channel)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | using System; using System.ServiceModel; namespace Client { class Program { static void Main( string [] args) { using ( var cf = new ChannelFactory<ICar>( "car" )) { Console.WriteLine(cf.CreateChannel().Run(3)); Console.Read(); } } } } |
上述内容概述了wcf Code和Config2种方式。在实际开发中,可以更简单通过vs的引用服务生成代理类,配置wcf服务工具修改*.config。本文就不再赘述了。
代码下载:等待整理
本文作者:Never、C
本文链接:http://www.cnblogs.com/neverc/p/4682394.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义