Web Service之客户端代理
代理类文件:
在客户端使用程序中生成的Reference.cs的文件即代理类,Service1.wsdl为相应的XML文件
代理类说明:
1. 代理类开始是引出一系列的命名空间,代码的主题是定义一个跟待访问的Web服务类同名的 从System.Web.Services.Protocols.HttpGetClientProtocol派生的代理类
2. 代理类具有如下四个方法
2.1 不带参数的构造函数
构造函数主要是设定代理类的URL属性,这个属性表示WEB服务的URL.
2.2 doSearch方法
该方法是WEB服务的doSearch方法的本地代理版本,该方法被一个HttpMethodAttribute所标注,其目的是指示如何序列化发送到 WEB服务的doSearch方法的参数以及如何反序列化WEB服务的响应.如果采用HTTP-GET调用WEB服务的方法,则必须把 HTTPMothodAttribute的ReturnFormatter属性设置为 XmlReturnReader,ParameterFormatter属性设置为UrlParameterWriter.
方法的返回值也被一个XmlRootAttribute特性所标记.该特性用以将类,结构,枚举或结口标记为XML文档实例的根(或项级)元素.该特性的 ElementName属性表示返回值对应的XML元素的名称,Namespace属性表示XML根元素的命名空间,IsNullable属性表示返回值为空时ElementName所指的无素是否包xsi:nil属性.
以上特性其实代替了我在C#分类中所讲的利用HTTP-GGET;HTTP-POST来获得WEB服务中的设置URL,在URL中附中参数,以及从返回XML文档中提结果的大段代码
再来看看方法中的代码
return ((string)(this.Invoke("doSearch", (this.Url + "/doSearch"), new object[] { keyword})));
上述代码先调用一个Invoke方法,(该方法继承自父类HttpGetClientProtocol),然后把调用结果强制转化为字符串类型.
Invoke方法的原型:
protected Object Invoke(string MethodName,string RequestUrl,Object[] Parameters);
参数:MethodName->表示要调用的Web服务的名称,本例中的“doSearch“
参数:RequestUrl->表示WEB服务的方法的URL,它是由WEB服务的URL加上"/方法名"组成
参数:Parameters->是一个对象数组,包含要传递到远程WEB服务的参数,数组中的顺序与派生类的调用方法中的参数顺序对应
返回值包含派生类方法的返回值和所有引用或输出参数的对象数组
2.3 BegindoSearch方法
这个方法用以启动对WEB服务的doSearch方法的异步调用
BegindoSearch的参数:
keyword: 参数.
callback: AsyncCallback类型的委托对象,当异步调用结束后,callback所代表的函数将被回调,用来接收结果.
AsyncCallback委托原型:
[Serializable]
public delegate void AsyncCallback(IAsyncResult ar);
其: IAsyncResult接口:用于监视和管理异步操作.
IAsyncResult接口的原型
public interface IAsyncResult
{
object AsyncState{get;}//返回被作为最后一个参数提供的对象
WaitHandle AsyncWaitHandle{get;}//返回WaitHandle,它可用于执行WaitHandle.WaitOne,WaitAny,WaitAll,以实现同步
bool CompletedSynchronously{get;}//如果开始操作同步完成,则CompletedSynchronously=true
bool IsCompleted{get;}//在服务器完成调用处理后IsCompleted=true
}
2.4 EnddoSearch方法
这个方法用以结束异步调用,并获得调用结果
代理的作用:
客户端应用程序如果使用Web Service,必须先创建一个代理。代理是要调用的真正代码的替身,它负责在机器边界引导调用。在代理在客户端应用程序中注册后,客户端应用程序调用方法就如调用本地对象一样。代理接受该调用,并以适当格式封装调用,然后以SOAP请求发送调用到服务器。当服务器返回SOAP包给客户端后,代理会对包进行解密,并且如同从本地对象的方法返回数据一样将其返回给客户端应用程序。
代理的生成:
1。可以使用vs自动生成一个代理,并在使用程序中通过将web引用添加到程序中,注册该代理;2。可以是用wsdl.exe命令来创建代理类源码。
下面是手工生成代理类的步骤:
1、vs的命令提示工具,输入:C:\>wsdl http://localhost/StockWebService/Service1.asmx /n:localhost,其中,localhost是自定义的命名空间。提示如下:
Microsoft (R) Web 服务描述语言实用工具
[Microsoft (R) .NET Framework,版本 1.1.4322.573]
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.
正在写入文件“C:\Service1.cs”。
2、注意,此时在C:盘(其实就是命令提示符的当前目录)下生成一个和Service1.asmx相同文件名的C#源文件Service1.cs。
3、编译Service1.cs文件,在命令提示符下输入如下命令:C:\>csc /out:ServiceDll.dll /t:library /r:System.Web.Services.dll c:\Service1.cs。其中,/out:ServiceDll.dll是要输出的dll文件,/t:library是输出文件类型,/r:System.Web.Services.dll是要引用的组件,c:\Service1.cs是第4步生成的C#文件。
4、此时,将会在C:盘下生成一个叫ServiceDll.dll的文件,要使用这个文件,必须复制到StockWebService文件夹下的bin目录下。默认情况下为:C:\Inetpub\wwwroot\StockWebService\bin。
5、新建一个名为TestWSDL.aspx的WEB窗体文件,并添加一个引用,将刚才生成的ServiceDll.dll文件作为引用添加到工程中。
使用异步方法调用
正如前面中提到的,Web Service允许程序员调用任何web方法,无论它是同步的还是异步的。
当方法是同步的,方法调用就是普通调用,程序将等待方法返回后再继续执行。只要方法没有用太长时间来处理,且网络延时不是很久的情况下,这样的停顿不是问题。如下图,演示了同步处理,通过代理调用服务器上的方法。调用程序并不知道还有一个代理在处理过程中进行干预,直到调用结果返回之后,调用程序才会继续处理。
然而,当方法需要消耗很长的时间来处理时(例如,一个很长的数据库操作或者扩展计算)或者网络延迟很明显的时候,这样的延迟就是一个不可接受的性能瓶颈。当web service的方法调用需要在Internet上做一个较长的“旅行”的时候,那么网络长延迟就很常见。这时,宽带Internet连接对于解决这个玩呢提有帮助,但是仍然会有性能问题。
一种解决方案是:异步处理。在这种模型下,Web Service的方法将通过指令被调用,而这种指令会在结果准备好后,通知客户端。客户端不需要等待返回的结果,却可以继续它的业务。当异步方法完成后会调用一个回调方法,然后客户端就可以从服务器获得数据。如下图所示:
与同步方法调用相同,客户端不知道代理截获了方法调用,并把它传递给服务器。客户端事件处理程序调用web Service中的(实际上是代理类中)的Begin...方法,并传入一个回调方法的委托(即上图中的1)。客户端则继续做其他事情。代理代表客户端调用Web方法(2),当服务器完成对方法的执行后,返回一个结果到代理中(3)。代理调用客户端回调方法然后传入一个实现了IAsyncResult的对象(4)。然后,客户端把IAsyncResult返回给代理的End..方法(5)。End...方法再把数据返回到哦客户端(6)。
客户端不需要盯着服务器,因为当方法执行完毕后,回调会通知客户端。回调方法是一个代理,它是指定签名和返回类型封装方法的引用类型。异步的Begin和End方法为你在客户端中实现的回调机制定义了一个委托。