WCF 招标代理工作怎么样 是怎么工作的

/blog/2308191
自托管Self Hosting&
如果是web服务,我们只能将服务托管在IIS上,但是WCF提供了让服务可以托管在任何应用程序(比如控制台应用程序,Windows Form等等)中的能力。许多有趣开发者有责任提供和管理托管进程的生命周期。服务端和客户端可以同时存在在相同的进程中。现在,让我们创建一个托管在控制台应用程序中的WCF服务。我们将会以抽象类ClientBase为基类创建一个代理。&
Note:托管程序必须在客户端访问之前运行,这也意味着你得预启动它。&
Step1: 让我们从创建服务七月和它的实现开始吧。创建一个控制台应用程序,并且命名为MyCalculatorService。这是一个简单的服务,它只是返回两个数想加的和。&
Step 2: 添加System.ServiceModel引用&
Step 3: 创建ISimpleCalculator接口,加入ServiceContract和OperationContract到类和方法上,你会在随后的内容中了解它们的作用。这些Attribute将会把服务公布给调用方。&
IMyCalculatorService.cs&
using&System.Collections.G&&
using&System.L&&
using&System.T&&
using&System.ServiceM&&
namespace&MyCalculatorService&&
&&&&[ServiceContract()]&&
&&&&public&interface&ISimpleCalculator&&
&&&&&&&&[OperationContract()]&&
&&&&&&&&int&Add(int&num1,&int&num2);&&
Step 4: 如下所示,MyCalculatorService是IMyCalculatorService接口的实现类&
MyCalculatorService.cs&
using&System.Collections.G&&
using&System.L&&
using&System.T&&
namespace&MyCalculatorService&&
&&&&class&SimpleCalculator&:&ISimpleCalculator&&
&&&&&&&&public&int&Add(int&num1,&int&num2)&&
&&&&&&&&{&&
&&&&&&&&&&&&return&num1&+&num2;&&
&&&&&&&&}&&
Step 5: 现在服务已经准备好了,让我们开始实现托管进程吧,创建一个新的控制台应用程序MyCalculatorServiceHost&
Step 6: ServiceHost是托管WCF服务的核心类。它的构造函数可以接受已经实现了的契约类和服务地址作为参数,你可以用逗号分隔注册多个基地址,但是地址必须基于同样的传输协议(http等)&
Uri&httpUrl&=&new&Uri(&http://localhost:8090/MyService/SimpleCalculator&);&&
Uri&tcpUrl&=&new&Uri(&net.tcp://localhost:8090/MyService/SimpleCalculator&);&&
ServiceHost&host&=&new&ServiceHost(typeof(MyCalculatorService.SimpleCalculator),&httpUrl,&tcpUrl);&&
使用AddServiceEndpoint()可以加入多个终结点。host.Open()将启动服务,之后就可以为客户端提供服务了。&
Step 7: 以下程序说明了如果实现托管进程&
using&System.Collections.G&&
using&System.L&&
using&System.T&&
using&System.ServiceM&&
using&System.ServiceModel.D&&
namespace&MyCalculatorServiceHost&&
&&&&class&Program&&
&&&&&&&&static&void&Main(string[]&args)&&
&&&&&&&&{&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&Uri&httpUrl&=&new&Uri(&http://localhost:8090/MyService/SimpleCalculator&);&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&ServiceHost&host&&&
&&&&&&&&&&&&=&new&ServiceHost(typeof(MyCalculatorService.SimpleCalculator),&httpUrl);&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&host.AddServiceEndpoint(typeof(MyCalculatorService.ISimpleCalculator)&&
&&&&&&&&&&&&,&new&WSHttpBinding(),&&&);&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&ServiceMetadataBehavior&smb&=&new&ServiceMetadataBehavior();&&
&&&&&&&&&&&&smb.HttpGetEnabled&=&true;&&
&&&&&&&&&&&&host.Description.Behaviors.Add(smb);&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&host.Open();&&
&&&&&&&&&&&&Console.WriteLine(&Service&is&host&at&&&+&DateTime.Now.ToString());&&
&&&&&&&&&&&&Console.WriteLine(&Host&is&running...&Press&&Enter&&key&to&stop&);&&
&&&&&&&&&&&&Console.ReadLine();&&
&&&&&&&&}&&
Step 8: 服务一旦被托管启动,我们就可以创建为客户端服务的带来类了,创建代理有不同的方法&
&&& 1.使用SvcUtil.exe创建代理以及相关联的配置文件&
&&& 2.将服务引用添加到客户端程序&
&&& 3.实现基类ClientBase&T&&
在这些方法中,实现ClientBase&T&是最好的实践。假如你使用另外两个,当服务实现发生变化的时候,你需要每次都创建代理类。但是使用ClientBase&T&就不需要。它会在启动的时候创建代理,所以它可以处理任何变化。&
MyCalculatorServiceProxy.cs&
using&System.Collections.G&&
using&System.L&&
using&System.T&&
using&System.ServiceM&&
using&MyCalculatorS&&
namespace&MyCalculatorServiceProxy&&
&&&&public&class&MyCalculatorServiceProxy&:&&&
&&&&&&&&&&
&&&&&&&&ClientBase&ISimpleCalculator&,&&
&&&&&&&&ISimpleCalculator&&
&&&&&&&&public&int&Add(int&num1,&int&num2)&&
&&&&&&&&{&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&return&base.Channel.Add(num1,&num2);&&
&&&&&&&&}&&
Step 9: 在客户端,我们创建代理类的实例,并且使用如下的方法调用,将代理dll的参照加入到这个工程中。&
using&System.Collections.G&&
using&System.L&&
using&System.T&&
using&System.ServiceM&&
namespace&MyCalculatorServiceClient&&
&&&&class&Program&&
&&&&&&&&static&void&Main(string[]&args)&&
&&&&&&&&{&&
&&&&&&&&&&&&MyCalculatorServiceProxy.MyCalculatorServiceProxy&proxy&;&&
&&&&&&&&&&&&proxy=&new&MyCalculatorServiceProxy.MyCalculatorServiceProxy();&&
&&&&&&&&&&&&Console.WriteLine(&Client&is&running&at&&&+&DateTime.Now.ToString());&&
&&&&&&&&&&&&Console.WriteLine(&Sum&of&two&numbers...&5+5&=&+proxy.Add(5,5));&&
&&&&&&&&&&&&Console.ReadLine();&&
&&&&&&&&}&&
Step 10 : 终结点信息需要被加入到客户端程序的配置文件中。&
&version=&1.0&&encoding=&utf-8&&&&
&&&&&&&&&&
&&&&&&&&&&&&&address&=&http://localhost:8090/MyService/SimpleCalculator&&&&
&&&&&&&&&&&&&&&&&&&&binding&=&wsHttpBinding&&&
&&&&&&&&&&&&&&&&&&&&contract&=&MyCalculatorService.ISimpleCalculator&&&
&&&&&&&&&&&&&&
&&&&&&&&&&
Step 11: 运行客户端之前,你需要先启动服务端,客户端的输出如下所示。&
自托管展现了in-Pro hosting的好处。以编程的方式访问,并且可以编程为单例服务。我系统你会喜欢上自托管的方式,现在让我们进入下一步,将服务托管在Windows Activation service中。
==================================================================================================================
我们之所以说WCF比一般的Web Service要强大得多,是因为它要比一般的Web服务要灵活得多,而且它不仅仅能在IIS服务器上运行,其实它可以用很多种方法来运行,哪怕一个控制台应用程序。
现在,大家可以回忆一下前面我写的《传说中的WCF》,我上面的例子绝大多数都是控制台应用程序类型的。我们应当把WCF理解为一种通信技术,而不只是服务。前面的例子中我是告诉大家,完成服务器端后,就在客户端项目中添加服务引用,这样就生成了客户端代理类,我们就可以像平时使用一般类型一样使用了。
其实按照我们前面所讲的方法,也足以完成许多实际任务了。大家是否还想拓展一下呢? 有朋友肯定会问了:再拓展会不会变得很难? 放心吧,不会很难,相信我,老周从来不会讲大家都看不懂的东西的。
我们现在不妨尝试一下,在客户端不添加服务引用,而是由我们自己来编写调用服务的代理类。要做到这一点,首先我们要明确的,其实我们所编写的服务协定,在服务器和客户端都需要用到,如果大家查看过添加服务引用时由工具生成的代码,会发现其实它在客户端也生成了服务协定的代码。所以,在我们手动编写调用服务的代码时,也需要这样,因此有两种方法可以在服务器和客户端之间共用服务协定,一是把代码复制一下粘贴到客户端中,另一种方法,我们可以新建一个类库,然后把服务协定写到这个类库中,最后在服务器端和客户端都引用这个类库即可。举个例子,假如有以下定义的协定:
[csharp]&&
然后,我们在服务器端实现协定,注意:接口在服务器端实现即可,客户端不需要。
[csharp]&&
接着,和以前一样,创建服务主机,并侦听客户端调用。
[csharp]&&
大家可以细心看一下,和以前的代码有什么不同? 不妨比较一下,看看。
1、以前,我们在创建ServiceHost时会指定一个HTTP基地址,但这里不需要了,基址是便于工具生成代理类的,我们既然要手动来写了,就不用生成代码了,也不用基址了。
2、以前,我们会在ServiceHost.Description.Behaviors集合中加一个ServiceMetadataBehavior对象,以提供WSDL,帮肋工具生成代码。现在我们都自己手动写了,当然就不用提供WSDL了。
认真想想,看是不是这样? 如果你有兴趣,也可以为ServiceHost弄一个基址,但不添加ServiceMetadataBehavior,然后在客户端项目中添加引用,你会发现……呵呵,你懂的。
那现在在客户端怎么调用服务呢? 使用通道,可能有朋友会看到IChannel接口,又派生出很多接口,但貌似没有一个是类的,是不是要自己来写通道啊? 不用,当然你要扩展通道层是另一回事,通常我们无需扩展通道,因为现有的已经足够牛逼了。我们在“对象浏览器”中是看不到与通道相关的可用的类,因为.NET内部是有实现的,只是没有定义为public而已,是internal。
我们根本可以不必理会如何找通道的问题,就好像我们坐在一辆全自动导航或者有专业司机驾驶的车上,司机知道怎么走,我们不必要担心不知道怎么走这段路。同理,我们可以不直接操作通道,为什么呢?因为我们定义的每一个服务协定都可以认为是一个通道。
上面我们定义的那么ITest就是一个通道,WCF内部已经帮我们把它变成一个通道了,不信的话,你往后看例子。
我们已经知道,编写的服务协定可以当成一个通道来操作,所以,在客户端中,我们要手动写代码来调用服务,要可以遵循以下步骤,有兴趣的话你可以背下来,但告诉你,背了没用。
1、创建与服务器匹配的Binding,这个就不用怀疑的了,你跟别人签合同,那肯定是一式两份,对方持一份,你拿一份,你肯定不会拿一张白纸回家保存吧。
2、创建通道,使用ChannelFactory&TChannel&类可以创建通道,因为它是“工厂”嘛,工厂当然是用来生产的,但ChannelFactory工厂不是用来生产老鼠药也不是生产地雷的,它是专门生产Channel(通道)的。这个TChannel就可以写上你定义的服务协定的接口,如上面的ITest。
3、得到的通道就是ITest,然后就可以调用服务了,比如要两个数相加,就调用ITest.Add。
4、关闭通道,把ITest强制转换为IClientChannel就可以调用Close方法关闭通道。
可能你对这些步骤还有疑问,没关系,你不妨先疑一下。我们继续往下操作。
前面定义服务主机的时候,我们使用了两个终结点,一个是HTTP的,另一个是TCP调用。所以我们这里也要分别用这两种方法调用。我可没说一定要用这两种方法调用,我只是多写了一个作演示。
在客户端,先声明这两个终结点地址,就是我们在服务器定义的两个地址。
[csharp]&&
然后,分别用两种Binding调有服务。
[csharp]&&
你也许会问,ITest不是接口来的吗,怎么可以调用? 别忘了,我们在服务器端已经实现过了,WCF内部会帮我们找到关联的类。
现在,你就兴奋地看看结果吧。记着,运行服务器端需要管理员身份运行,这个我说了三千五百遍了。
嘿嘿,乍一看,好像可以了,已经能调用了,但是,这样是不是不太简洁呢? 而且我们不能将其当成一人类来用,每次调用要通过ChannelFactory来生产,比较麻烦,更重要的是,如果有服务器回调协定,就不好弄了。
因此,对于上面的客户端代码我们是否考虑进一个封装呢? 这里我们完全可以考虑使用ClientBase&TChannel&类,它对于通道和相关操作作了进一步封装,当然它是抽象类,不能直接拿来玩,要先派生出一个类。
[csharp]&&
有人会问,为什么从ClientBase&CommonLib.ITest&派生,又要实现一次CommonLib.ITest接口呢? 当然,你不实现也无所谓,再实现一次CommonLib.ITest接口是为了让这个类的公共方法和ITest的方法一样,这样方便调用。
通过访问base.Channel就可以得到一个对ITest的引用,无需要我们自己创建通道,因为基类中已经带了默认实现。
现在,把前面的调用代码改一下,是不是觉得简洁了?
[csharp]&&
现在看看我们自己写的这段代码,是不是与VS生成的代码比较接近了? 而且连配置文件也省了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
(10)(15)(6)(18)(2)(13)(12)(18)(28)(5)(24)(40)(21)(17)(27)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'使用代理类访问WCF应用(不添加web引用、不使用管道模式)以及如何调试WCF(转过来的)
使用.NET做分布式,我们首先会想到WebService、Remoting、WCF,这里我以WCF为例,简单讲解下如何使用代理来访问WCF服务(不添加web引用、不使用管道模式【因为管道模式依赖于WCF的契约】)。
1.生成代理类
1)打开VS命令行工具,使用命令:svcutil&契约的dll完整路径
2)它会在dll所在目录下生成几个文件,其中包含一个wsdl文件和一个xsd文件
3)使用命令:svcutil *.wsdl *.xsd
4)这时会在dll所在目录生成一个.cs文件,这个就是我们需要的代理类了
5)现在客户端调用WCF服务我们就可以使用这个代理类来完成了,具体如下:
IService service = new ServiceClient(Binding, new
EndpointAddress(Address));
service.Execute();
注:Execute方法为契约中定义的方法
2.如何调试WCF
1)解决方案上点右键-属性-启动项目-多启动项目,将你需要启动的项目设置为启动
2)按F5开始进行调试,在调试到访问WCF时,按F11前进,这样就可以调试到WCF内部去了。
3)有时我们在不调试时,需要在客户端看到WCF服务调用出错的信息,可以在宿主的配置文件中加入下面这段内容
&system.serviceModel&
&behaviors&
&serviceBehaviors&
&behavior&
&serviceDebug
includeExceptionDetailInFaults="true"/&
&/behavior&
&/serviceBehaviors&
&/behaviors&
&/system.serviceModel&
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。中国领先的IT技术网站
51CTO旗下网站
学习笔记教你使用WCF生成代理
随着WCF的发展,WCF的性能也随着提高,这里就WCF生成代理简单的介绍一下,希望大家通过读本文有技术上的提高。
作者:佚名来源:博客| 12:30
在编程中现在有一个词代理,想必大家也都知道,下面我们就WCF生成代理和大家分析一下。对于一个好的分布式系统来讲,设计时应当考虑到异构性、开放性、安全性、可扩展性、故障处理、并发性以及透明性等问题。基于SOAP的Web Service可以实现异构环境的互操作性,保证了跨平台的通信。
利用WSE(Web Service Enhancements)可以为ASMX提供安全性的保证。.NET Remoting具有丰富的扩展功能,可以创建定制的信道、格式化器和代理程序。Enterprise Service(COM+)提供了对事务的支持,其中还包括分布式事务,可实现故障的恢复。MSMQ可以支持异步调用、脱机连接、断点连接等功能,利用消息队列支持应用程序之间的消息传递。从功能角度来看,WCF整合了ASMX、.Net Remoting、Enterprise Service、WSE以及MSMQ等现有技术的优点,它提供了一种构建安全可靠的分布式面向服务系统的统一的框架模型,使软件研发人员在开发分布式应用时变得更加轻松。
(1)WCF生成代理类publicpartialclassSearchApplicationAdminWebServiceClient:System.ServiceModel.ClientBase,ISearchApplicationAdminWebService &{ &&publicSearchApplicationAdminWebServiceClient() &{ &InspectorBehaviormessageInspectorBehavior=base.ChannelFactory.Endpoint.Behaviors.Find(); &if(messageInspectorBehavior==null) &{ &base.ChannelFactory.Endpoint.Behaviors.Add(newInspectorBehavior()); &} &&} &.... &} &
(2)WCF生成代理利用channelFactoryChannelFactorychannelFactory=newChannelFactory("CustomBinding_ISearchApplicationAdminWebService"); &&InspectorBehaviormessageInspectorBehavior=channelFactory.Endpoint.Behaviors.Find(); &if(messageInspectorBehavior==null) &{ &channelFactory.Endpoint.Behaviors.Add(newInspectorBehavior()); &} &varserver=channelFactory.CreateChannel(); &【责任编辑: TEL:(010)】
大家都在看猜你喜欢
热点原创热点头条头条
24H热文一周话题本月最赞
讲师:428984人学习过
讲师:228287人学习过
讲师:30699人学习过
精选博文论坛热帖下载排行
本书详细介绍了AJAX在Web开发上的应用。主要内容包括:ASP.NET AJAX技术概述、实现异步局部更新页面、UpdatePanel编程功能、PageRequestMan...
订阅51CTO邮刊记录学习的点点滴滴。
转自/icyJ/p/DefaultProxy.html
程序是.net开发的winform工具,分服务器端和客户端,用wcf技术实现数据交互。
客户端是大型公司,内部统一使用代理服务器上网。具体描述为:在IE中设置lan代理服务器才能查询网络数据;登录QQ或其他联网程序(网络版金山词霸)时,需要打开程序的代理设置,填写相应的地址和端口,才能登录。
自行开发的.net程序这类问题怎么解决。
参考这里:
HomeLinkTransClient client = new HomeLinkTransClient(binding, epAddress);
client.ClientCredentials.UserName.UserName = "用户名";
client.ClientCredentials.UserName.Password = "密码";
此客户端代理是别人访问设置的用户名和密码
web.config配置才是网络代理&&system.net&&&&&&defaultProxy&useDefaultCredentials="true"&&/defaultProxy&&&&&&&&/system.net&以上web.config设置会默认的从浏览器中找到代理。
实际应用只在服务器端的web.config里面设置了下面的代码即可解决问题。
至于上面的client的设置,暂不清楚用处。
补充一:上面的方法并未解决实际用户的问题。
wcf的客户端代理为System.ServiceModel.ClientBase&IWcfService&类型的对象,每次链接wcf都是实例化此对象,然后发送请求。
本次的解决方法:
public class WcfClient
static readonly System.ServiceModel.BasicHttpBinding _B
/// &summary&
/// 默认wcf服务连接
/// &/summary&
public const string UriString = @"/wcf.svc";
static WcfClient()
_Binding = new BasicHttpBinding();
_Binding.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas() { MaxStringContentLength = 65536 }; //(更改这个数字)
//在这里设置代理
WebProxy proxy = new WebProxy("192.168.0.200:8765", false);
proxy.Credentials = new NetworkCredential("User", "psd");
System.Net.HttpWebRequest.DefaultWebProxy =
/// &summary&
/// 获取wcf服务
/// &/summary&
/// &param name="uri"&wcf服务连接&/param&
/// &returns&&/returns&
public static WcfServiceClient GetService(string uri = UriString)
var sc = new WcfServiceClient();
sc.Endpoint.Address = new EndpointAddress(new Uri(uri));
sc.Endpoint.Binding = _B
在上面的静态构造函数里面配置代理的属性,赋值给System.Net的默认代理设置即可。
遗留问题:通常代理的设置都有http/sockS5/sockS4/浏览器设置等,这里的代理设置应该是对http的代理设置,这几种代理设置是针对代理服务器的还是wcf数据传输方式?感觉应该是代理服务器的,如果是这样,那其他几种代理方式的程序设置应该怎么完成呢?
没看懂的资料:
/blog/2010/01/using_http_proxy_servers.html
阅读(...) 评论() &

我要回帖

更多关于 招标代理这个工作好吗 的文章

 

随机推荐