zoukankan      html  css  js  c++  java
  • 蛙蛙推荐:如何编写异步的WebService(不是异步调用WebService)

    如何编写异步的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();
            }
        }
    }

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

    代码下载:

    https://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);
              }

        }
    }

  • 相关阅读:
    <%%>,<%!%>,<%=%>,<%@%>,<jsp:include><%@ include%>区别
    struts2学习
    struts2标签
    OGNL
    Andriod XML Editor cannot process this input
    Error 错误: 找不到或无法加载主类
    Class<T> 与T区别
    poi
    POI-java读取Excel(包含合并单元格)
    SQL-字符串连接聚合函数
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/async_webservice.html
Copyright © 2011-2022 走看看