zoukankan      html  css  js  c++  java
  • HttpWebRequest 的一个 异步封装

    相信大家对HttpWebRequest这个类应该非常熟悉了吧。主要用它来模拟http请求,在有些时候我们需要用到它的异步处理,每次用的时候都要写很多代码,于是今天把它简单的封装了一下。虽然在C#4和C#5中它提供了很新方法是的异步更加简单,但是在一些老项目(还在用vs2005)上我们只能用C#2.0的语法来实现它的异步功能。

    如图1,这里的RequestInfo类是请求信息的一个封装,ResponseInfo类是返回对象的一个封装,StateObject是一个内部状态保存对象类(我们不需要关心),RequestHttpWebRequest是HttpWebRequest的一个封装类,只有一个公共方法:

        public void GetResponseAsync(RequestInfo info, Action<ResponseInfo> act)

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.Data;
    using System.Data.OleDb;
    using System.Net;
    using System.Xml;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    
    [Serializable]
    public class RequestInfo
    {
        public RequestInfo(string url)
        {
            Url = url;
            AllowAutoRedirect = true;
        }
        public string Url { set; get; }
        public byte[] PostData { set; get; }
        public WebHeaderCollection Headers { set; get; }
        public bool AllowAutoRedirect { set; get; }
        public Dictionary<string, string> ExternalData { set; get; }
    }
    
    [Serializable]
    public class ResponseInfo
    {
        public RequestInfo RequestInfo { set; get; }
        public Stream ResponseContent { set; get; }
        public HttpStatusCode StatusCode { set; get; }
        public WebHeaderCollection Headers { set; get; }
        public string GetString(Encoding coding)
        {
            StringBuilder str = new StringBuilder();
            Stream sr = ResponseContent;
            sr.Seek(0, SeekOrigin.Begin);
            byte[] data = new byte[1024 * 1024];
            int readcount = sr.Read(data, 0, data.Length);
            while (readcount > 0)
            {
                str.Append(coding.GetString(data, 0, readcount));
                readcount = sr.Read(data, 0, data.Length);
            }
            return str.ToString();
        }
    }
    
    internal class StateObject
    {
        public byte[] Buffer { set; get; }
        public ResponseInfo ResponseInfo { set; get; }
        public Stream ReadStream { set; get; }
        public HttpWebRequest HttpWebRequest { set; get; }
        public Action<ResponseInfo> Action { set; get; }
    
    }
    
    public class RequestHttpWebRequest
    {
        static RequestHttpWebRequest()
        {
            ServicePointManager.DefaultConnectionLimit = 100;
        }
        public RequestHttpWebRequest()
        {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
        }
        private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //直接确认,否则打不开  
            return true;
        }
        public void GetResponseAsync(RequestInfo info, Action<ResponseInfo> act)
        {
            HttpWebRequest webRequest;
            StateObject state;
            InitWebRequest(info, act, out webRequest, out state);
            try
            {
                if (info.PostData != null && info.PostData.Length > 0)
                {
                    webRequest.Method = "POST";
                    webRequest.ContentType = "application/x-www-form-urlencoded";
                    webRequest.BeginGetRequestStream(EndRequest, state);
                }
                else
                {
                    webRequest.BeginGetResponse(EndResponse, state);
                }
    
            }
            catch (Exception ex)
            {
                HandException(ex, state);
            }
        }
        void EndRequest(IAsyncResult ar)
        {
            StateObject state = ar.AsyncState as StateObject;
            try
            {
                HttpWebRequest webRequest = state.HttpWebRequest as HttpWebRequest;
                using (Stream stream = webRequest.EndGetRequestStream(ar))
                {
                    byte[] data = state.ResponseInfo.RequestInfo.PostData;
                    stream.Write(data, 0, data.Length);
                }
                webRequest.BeginGetResponse(EndResponse, state);
    
            }
            catch (Exception ex)
            {
                HandException(ex, state);
            }
        }
        void EndResponse(IAsyncResult ar)
        {
            StateObject state = ar.AsyncState as StateObject;
            try
            {
                HttpWebResponse webResponse = state.HttpWebRequest.EndGetResponse(ar) as HttpWebResponse;
                state.ResponseInfo.StatusCode = webResponse.StatusCode;
                state.ResponseInfo.Headers = new WebHeaderCollection();
                foreach (string key in webResponse.Headers.AllKeys)
                {
                    state.ResponseInfo.Headers.Add(key, webResponse.Headers[key]);
                }
                state.ReadStream = webResponse.GetResponseStream();
                state.ReadStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallBack, state);
            }
            catch (Exception ex)
            {
                HandException(ex, state);
    
            }
        }
        void ReadCallBack(IAsyncResult ar)
        {
            StateObject state = ar.AsyncState as StateObject;
            try
            {
                int read = state.ReadStream.EndRead(ar);
                if (read > 0)
                {
                    state.ResponseInfo.ResponseContent.Write(state.Buffer, 0, read);
                    state.ReadStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallBack, state);
                }
                else
                {
                    state.ReadStream.Close();
                    state.HttpWebRequest.Abort();
                    if (state.Action != null)
                    {
                        state.Action(state.ResponseInfo);
                    }
                }
            }
            catch (Exception ex)
            {
                HandException(ex, state);
            }
        }
        private void InitWebRequest(RequestInfo info, Action<ResponseInfo> act, out HttpWebRequest webRequest, out StateObject state)
        {
    
            webRequest = HttpWebRequest.CreateDefault(new Uri(info.Url)) as HttpWebRequest;
            webRequest.KeepAlive = true;
            webRequest.AllowAutoRedirect = info.AllowAutoRedirect;
            if (info.Headers != null && info.Headers.Count > 0)
            {
                foreach (string key in info.Headers.Keys)
                {
                    webRequest.Headers.Add(key, info.Headers[key]);
                }
            }
            //webRequest.Proxy = WebProxy.GetDefaultProxy();
            //webRequest.Proxy.Credentials = CredentialCache.DefaultCredentials;  
            // webResponse.Headers.Get("Set-Cookie");
            state = new StateObject
            {
                Buffer = new byte[1024 * 1024],
                HttpWebRequest = webRequest,
                Action = act,
                ResponseInfo = new ResponseInfo
                {
                    RequestInfo = info,
                    ResponseContent = new MemoryStream()
                }
            };
        }
    
        private void HandException(Exception ex, StateObject state)
        {
            string message = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " : " + state.ResponseInfo.RequestInfo.Url + " : " + ex.Message;
            Console.WriteLine(message);
        }
    }

    这里的几个类及其属性都很好明白,我就不说了。只是大家要注意一点的是ResponseInfo中ResponseContent属性是服务器返回的数据流,这里它是一个MemoryStream对象。
    说说简单的调用吧

     

    整个调用是不是很简单啊!有不对的地方欢迎大家拍砖!


  • 相关阅读:
    CodeForces Gym 100935G Board Game DFS
    CodeForces 493D Vasya and Chess 简单博弈
    CodeForces Gym 100935D Enormous Carpet 快速幂取模
    CodeForces Gym 100935E Pairs
    CodeForces Gym 100935C OCR (水
    CodeForces Gym 100935B Weird Cryptography
    HDU-敌兵布阵
    HDU-Minimum Inversion Number(最小逆序数)
    七月馒头
    非常可乐
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3049968.html
Copyright © 2011-2022 走看看