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

蛙蛙推荐:如何编写异步的WebService(不是异步调用WebService)

发布时间:2020-12-17 02:33:41 所属栏目:安全 来源:网络整理
导读:如何编写异步的WebService(不是异步调用WebService) 摘要:我们做webService的时候,如果在处理用户请求的时候需要进行异步IO操作,在异步IO完成前会有一个线程在那里同步等待,正在等待的请求太多的话会大大降低服务的吞吐量,asp.net2.0里有异步的HttpHand

如何编写异步的WebService(不是异步调用WebService)

摘要:我们做webService的时候,如果在处理用户请求的时候需要进行异步IO操作,在异步IO完成前会有一个线程在那里同步等待,正在等待的请求太多的话会大大降低服务的吞吐量,asp.net2.0里有异步的HttpHandler能解决这个问题,可.net2.0没给弄一个异步的webservice,这就需要我们自己去实现了。

分析:.net处理webservice请求大致是这样的
1、用SyncSessionlessHandler来接收客户端的soap请求;
2、把这些文本的xml构建SoapMessage,SoapMessage里包含SoapMethod及参数等信息。
3、根据uri来获取请求的是哪个WebService,然后用反射取出该WebService里包含WebMethodAttriube的方法。
4、用SoapMessage里信息和反射出来的MethodInfo去匹配,并用反射的方式去Invoke Webservice那个类的方法。
5、把那个方法返回的值再序列化成Soap格式返回给客户端。

当然只是大致分析,具体的处理还包含是否启用事务,是否启用Session,以及大量的请求验证,缓存反射信息等操作。

在客户端异步调用web服务端时候会使用AsyncSessionHandler和AsyncSessionlessHandler这两个异步httphandler,但如果客户端同步调用就不能使用了。

知道了原理之后,我们可以写一个异步httphandler,获取用户请求构建SoapMessage,获取参数信息后,去调用自己指定的方法,而不是默认要调用的方法,在我们指定的方法里发送异步IO请求,在异步IO完成后,我们再构建原来方法的返回值,序列化成Soap格式,返回给客户端,然后设置异步httphandler的IAsyncResult.IsCompleted为true。

具体的部分我已经封装好了,下面介绍一下步骤。
1、先设计好webservice,如下

using ?System;
using ?System.Web.Services;

namespace ?TestWS
{
????
public ? class ?UserInfo
????{
????????
public ? int ?Age;
????????
public ?DateTime?Birthday;
????????
public ? string ?Password;
????????
public ? bool ?Sex;
????????
public ? string ?Username;
????}

????
public ? class ?RegisterResult
????{
????????
public ? string ?Description;
????????
public ? int ?StatusCode;
????????
public ? string ?Username;
????}

????[WebService(Namespace?
= ? " http://www.fetionmm.com/ " )]
????[WebServiceBinding(ConformsTo?
= ?WsiProfiles.BasicProfile1_1)]
????
public ? class ?Service1?:?WebService
????{
????????[WebMethod]
????????
public ?RegisterResult?RegisterUser(UserInfo?userInfo)
????????{
????????????var?result?
= ? new ?RegisterResult();
????????????result.Username?
= ?userInfo.Username;
????????????result.StatusCode?
= ? 200 ;
????????????result.Description?
= ? " ok " ;
????????????
return ?result;
????????}
????}
}

2、写一个ashx文件,如下

using ?MySoapLib;

namespace ?TestWS
{
????
// 这个类要继承自SoapAsyncHandler,它会自动接收soap消息并调用匹配的方法
????
// 然后要编写和VirtualServiceUri所指向的webService有相同的方法,但返回值都是void,
????
// 在对请求处理完成时构造返回值,再调用asynch.WriteResult来向调用者返回SOAP消息
???? public ? class ?Handler1?:?SoapAsyncHandler
????{
????????
protected ? override ? string ?VirtualServiceUri
????????{
????????????
get ?{? return ? " /Service1.asmx " ;?}
????????}

????????
public ? void ?RegisterUser(UserInfo?userInfo)
????????{
????????????var?result?
= ? new ?RegisterResult();
????????????result.Username?
= ?userInfo.Username;
????????????result.StatusCode?
= ? 200 ;
????????????result.Description?
= ? " ok " ;
????????????asynch.WriteResult(result);
????????}
????}
}

3、编写调用者,设置代理类的uri为新的ashx,而不是默认的asmx,如下

using ?System;
using ?WSClient.localhost;

namespace ?WSClient
{
????
internal ? class ?Program
????{
????????
private ? static ? void ?Main( string []?args)
????????{
????????????Console.WriteLine(
" start " );
????????????var?service1?
= ? new ?Service1();
????????????service1.Url?
= ? " http://localhost:10514/Handler1.ashx " ;
????????????var?userInfo?
= ? new ?UserInfo();
????????????userInfo.Username?
= ? " onlytiancai " ;
????????????userInfo.Password?
= ? " password " ;
????????????userInfo.Age?
= ? 25 ;
????????????userInfo.Birthday?
= ?DateTime.Parse( " 1983-01-01 " );
????????????userInfo.Sex?
= ? false ;
????????????RegisterResult?result?
= ?service1.RegisterUser(userInfo);
????????????Console.Write(
" name:{0},status:{1},desc,{2} " ,?result.Username,
??????????????????????????result.StatusCode,?result.Description);
????????????Console.ReadKey();
????????}
????}
}

具体的原理,大家看看代码吧,再挑挑毛病。

代码下载:

http://files.cnblogs.com/onlytiancai/AsyncWebService.zip

?

此文撤回,原来实现服务端的异步web服务有官方方法,我先去吃饭,回来再试试,汗了,白浪费哥们呕心沥血几十载把代码扣出来了。

http://www.microsoft.com/india/msdn/events/Inside%20ASP.NET%20Runtime.zip_

http://fhict.fontys.nl/Deeltijd/1JarigeStudies/CSA/Lesmateriaal/Week%202/Achtergrond/WebServicesTutorial.ppt

?

Server-Side Asynchronous Calls

???????? Can implement asynchronous design patterns in your Web service

?????????????????? Asynchronous Web method pattern

?????????????????? Custom pattern ?????

???????? Mitigate risk of operation timeout

???????? Perform lengthy operations on a different thread

???????? Client proxy usage doesn’t change

?

Asynchronous Web Methods

???????? WebServiceHandlerFactory

?????????????????? Default IHttpHandlerFactory assigned to process Web service extensions (*.asmx)

?????????????????? Uses reflection to determine if method to invoke is implemented synchronously or not

?????????????????? Returns appropriate IHttpHandler object to process the Web method request

?

Web Service Handlers

???????? System.Web.Services.Protocols

?????????????????? Contains (undocumented) handlers

?????????????????? Functionality varies based on session and asynchronous method implementation

???????? Handlers:

?????????????????? SyncSessionHandler

?????????????????? AsyncSessionHandler

?????????????????? SyncSessionlessHandler

?????????????????? AsyncSessionlessHandler

?

BeginXXX()/EndXXX() Methods

???????? Replace single Web method with asynchronous method pair

???????? Follow asynchronous design pattern for method signatures

?

???????? [WebMethod]

???????? public IAsyncResult BeginSleeper2(int mm,AsyncCallback cb,object state)

???????? {...}

????????

???????? [WebMethod]

???????? public string EndSleeper2(IAsyncResult ar)

???????? {...}

?

???????? WSDL still exposes a single method for the pair

???????? Framework handles invocation of asynchronous methods

?????????????????? Frees service thread to handle other requests

?????????????????? EndXXX() is invoked by handler when framework receives callback

?

Custom Asynchronous Pattern

???????? Implement complex server-side threading behaviors

???????? Provide methods to query status and request results

???????? Provide storage of results for transmission on request

?

测试通过,我汗死。

using ?System;
using ?System.Web.Services;

namespace ?TestWS
{
????[WebService(Namespace?
= ? " http://www.fetionmm.com/ " )]
????[WebServiceBinding(ConformsTo?
= ?WsiProfiles.BasicProfile1_1)]
????
public ? class ?Service1?:?WebService
????{
??????
????????[WebMethod]
????????
public ?IAsyncResult?BeginRegisterUser(UserInfo?userInfo,AsyncCallback?cb,? object ?state)
????????{
????????????RegisterUserDeleate?d?
= ?RegisterUser;
????????????
return ?d.BeginInvoke(userInfo,?cb,?d);
????????}

????????
private ? delegate ?RegisterResult?RegisterUserDeleate(UserInfo?userInfo);
????????
public ?RegisterResult?RegisterUser(UserInfo?userInfo)?{
????????????RegisterResult?result?
= ? new ?RegisterResult();
????????????result.Username?
= ?userInfo.Username;
????????????result.StatusCode?
= ? 200 ;
????????????result.Description?
= ? " ok " ;
????????????
return ?result;
????????}

??????????[WebMethod]
????????
public ?RegisterResult?EndRegisterUser(IAsyncResult?ar)
??????????{
??????????????RegisterUserDeleate?d?
= ?ar.AsyncState? as ?RegisterUserDeleate;
??????????????
return ?d.EndInvoke(ar); ??????????} ????} }

(编辑:李大同)

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

    推荐文章
      热点阅读