当前位置: 首页 > news >正文

异步发送HTTP请求

Http异步请求




AsyncHttpRequestHelperV2.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Imps.Services.CommonV4;
using System.Diagnostics;
using System.Net;
using System.IO;


namespace Imps.Services.IDCService.Utility
{
    public class AysncHttpRequestHelperV2
    {
        public static readonly ITracing _logger = TracingManager.GetTracing(typeof(AysncHttpRequestHelperV2));


        private AsynHttpContext _context;
        private byte[] buffer;
        private const int DEFAULT_LENGTH = 1024 * 512;
        private const int DEFAULT_POS_LENGTH = 1024 * 16;
        private bool notContentLength = false;
        private Action<AsynHttpContext, Exception> _action;
        private Stopwatch _watch = new Stopwatch();
        private byte[] requestBytes;


        private AysncHttpRequestHelperV2(HttpWebRequest request, Action<AsynHttpContext, Exception> callBack)
            : this(new AsynHttpContext(request), callBack)
        {
        }
        private AysncHttpRequestHelperV2(AsynHttpContext context, Action<AsynHttpContext, Exception> callBack)
        {
            this._context = context;
            this._action = callBack;
            this._watch = new Stopwatch();
        }


        public static void Get(HttpWebRequest request, Action<AsynHttpContext, Exception> callBack)
        {
            AysncHttpRequestHelperV2 proxy = new AysncHttpRequestHelperV2(request, callBack);
            proxy.SendRequest();
        }
        public static void Get(AsynHttpContext context, Action<AsynHttpContext, Exception> callBack)
        {
            AysncHttpRequestHelperV2 proxy = new AysncHttpRequestHelperV2(context, callBack);
            proxy.SendRequest();
        }


        public static void Post(HttpWebRequest request, byte[] reqBytes, Action<AsynHttpContext, Exception> callBack)
        {
            AysncHttpRequestHelperV2 proxy = new AysncHttpRequestHelperV2(request, callBack);
            proxy.SendRequest(reqBytes);
        }
        public static void Post(AsynHttpContext context, byte[] reqBytes, Action<AsynHttpContext, Exception> callBack)
        {
            AysncHttpRequestHelperV2 proxy = new AysncHttpRequestHelperV2(context, callBack);
            proxy.SendRequest(reqBytes);
        }
        public static void Post(HttpWebRequest request, string reqStr, Action<AsynHttpContext, Exception> callBack)
        {
            AysncHttpRequestHelperV2 proxy = new AysncHttpRequestHelperV2(request, callBack);
            proxy.SendRequest(Encoding.UTF8.GetBytes(reqStr));
        }
        public static void Post(AsynHttpContext context, string reqStr, Action<AsynHttpContext, Exception> callBack)
        {
            AysncHttpRequestHelperV2 proxy = new AysncHttpRequestHelperV2(context, callBack);
            proxy.SendRequest(Encoding.UTF8.GetBytes(reqStr));
        }


        /// <summary>
        /// 用于http get
        /// </summary>
        /// <param name="req">HttpWebRequest</param>
        /// <param name="action"></param>
        private void SendRequest()
        {
            try
            {
                _watch.Start();
               
                _context.RequestTime = DateTime.Now;
                IAsyncResult asyncResult = _context.AsynRequest.BeginGetResponse(RequestCompleted, _context);
            }
            catch (Exception e)
            {
                _logger.Error(e, "send request exception.");
                EndInvoke(_context, e);
            }
        }


        /// <summary>
        /// 用于POST
        /// </summary>
        /// <param name="req">HttpWebRequest</param>
        /// <param name="reqBytes">post bytes</param>
        /// <param name="action">call back</param>
        private void SendRequest(byte[] reqBytes)
        {
            try
            {
                _watch.Start();
                requestBytes = reqBytes;
                _context.AsynRequest.Method = "POST";
                _context.RequestTime = DateTime.Now;


                IAsyncResult asyncRead = _context.AsynRequest.BeginGetRequestStream(asynGetRequestCallBack, _context.AsynRequest);
            }
            catch (Exception e)
            {
                _logger.Error(e, "send request exception.");
                EndInvoke(_context, e);
            }
        }


        private void asynGetRequestCallBack(IAsyncResult asyncRead)
        {
            try
            {
                HttpWebRequest request = asyncRead.AsyncState as HttpWebRequest;
                Stream requestStream = request.EndGetRequestStream(asyncRead);
                requestStream.Write(requestBytes, 0, requestBytes.Length);
                requestStream.Close();
                SendRequest();
            }
            catch (Exception e)
            {
                _logger.Error(e, "GetRequestCallBack exception.");
                EndInvoke(_context, e);
            }
        }
        private void asynGetRequestCallBack2(IAsyncResult asyncRead)
        {
            try
            {
                HttpWebRequest request = asyncRead.AsyncState as HttpWebRequest;
                Stream requestStream = request.EndGetRequestStream(asyncRead);
                requestStream.BeginWrite(requestBytes, 0, requestBytes.Length, endStreamWrite, requestStream);
            }
            catch (Exception e)
            {
                _logger.Error(e, "GetRequestCallBack exception.");
                EndInvoke(_context, e);
            }
        }
        private void endStreamWrite(IAsyncResult asyncWrite)
        {
            try
            {
                Stream requestStream = asyncWrite.AsyncState as Stream;
                requestStream.EndWrite(asyncWrite);
                requestStream.Close();
                SendRequest();
            }
            catch (Exception e)
            {
                _logger.Error(e, "GetRequestCallBack exception.");
                EndInvoke(_context, e);
            }
        }


        private void RequestCompleted(IAsyncResult asyncResult)
        {
            AsynHttpContext _context = asyncResult.AsyncState as AsynHttpContext;
            try
            {
                if (asyncResult == null) return;
                _context.AsynResponse = (HttpWebResponse)_context.AsynRequest.EndGetResponse(asyncResult);
            }
            catch (WebException e)
            {
                _logger.Error(e, "RequestCompleted WebException.");
                _context.AsynResponse = (HttpWebResponse)e.Response;
                if (_context.AsynResponse == null)
                {
                    EndInvoke(_context, e);
                    return;
                }
            }
            catch (Exception e)
            {
                _logger.Error(e, "RequestCompleted exception.");
                EndInvoke(_context, e);
                return;
            }
            try
            {
                AsynStream stream = new AsynStream(_context.AsynResponse.GetResponseStream());
                stream.Offset = 0;
                long length = _context.AsynResponse.ContentLength;
                if (length < 0)
                {
                    length = DEFAULT_LENGTH;
                    notContentLength = true;
                }
                buffer = new byte[length];
                stream.UnreadLength = buffer.Length;
                IAsyncResult asyncRead = stream.NetStream.BeginRead(buffer, 0, stream.UnreadLength, new AsyncCallback(ReadCallBack), stream);
            }
            catch (Exception e)
            {
                _logger.Error(e, "BeginRead exception.");
                EndInvoke(_context, e);
            }
        }


        private void ReadCallBack(IAsyncResult asyncResult)
        {
            try
            {
                AsynStream stream = asyncResult.AsyncState as AsynStream;
                int read = 0;
                if (stream.UnreadLength > 0)
                    read = stream.NetStream.EndRead(asyncResult);
                if (read > 0)
                {
                    stream.Offset += read;
                    stream.UnreadLength -= read;
                    stream.Count++;
                    if (notContentLength && stream.Offset >= buffer.Length)
                    {
                        Array.Resize<byte>(ref buffer, stream.Offset + DEFAULT_POS_LENGTH);
                        stream.UnreadLength = DEFAULT_POS_LENGTH;
                    }
                    IAsyncResult asyncRead = stream.NetStream.BeginRead(buffer, stream.Offset, stream.UnreadLength, new AsyncCallback(ReadCallBack), stream);
                }
                else
                {
                    _watch.Stop();
                    stream.NetStream.Dispose();
                    if (buffer.Length != stream.Offset)
                        Array.Resize<byte>(ref buffer, stream.Offset);
                    _context.ExecTime = _watch.ElapsedMilliseconds;
                    _context.SetResponseBytes(buffer);
                    _action.Invoke(_context, null);
                }
            }
            catch (Exception e)
            {
                _logger.Error(e, "ReadCallBack exception.");
                EndInvoke(_context, e);
            }
        }


        private void EndInvoke(AsynHttpContext _context, Exception e)
        {
            try
            {
                _watch.Stop();
                _context.ExecTime = _watch.ElapsedMilliseconds;
                _action.Invoke(_context, e);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "EndInvoke exception.");
                _action.Invoke(null, ex);
            }
        }


    }
}





AsyncHttpContext.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;


namespace AsyncHttpRequestDemo
{
    public enum AsynStatus { Begin, TimeOut, Runing, Completed }


    public class AsynHttpContext : IDisposable
    {
        private HttpWebRequest _asynRequest;
        private HttpWebResponse _asynResponse;
        private DateTime _requestTime;
        private long _execTime;
        bool isDisposable = false;
        private byte[] _rspBytes;




        public long ExecTime
        {
            get { return _execTime; }
            set { _execTime = value; }
        }
        public byte[] ResponseBytes
        {
            get { return _rspBytes; }
        }


        public HttpWebRequest AsynRequest
        {
            get { return _asynRequest; }
        }
        public HttpWebResponse AsynResponse
        {
            get { return _asynResponse; }
            set { _asynResponse = value; }
        }
        public DateTime RequestTime
        {
            get { return _requestTime; }
            set { _requestTime = value; }
        }
        private AsynHttpContext() { }
        public AsynHttpContext(HttpWebRequest req)
        {
            _asynRequest = req;
        }
        public void SetResponseBytes(byte[] bytes)
        {
            _rspBytes = bytes;
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        public void OnTimeOut()
        {
            if (_asynRequest != null)
                _asynRequest.Abort();
            this.Dispose();
        }
        private void Dispose(bool disposing)
        {
            if (!isDisposable)
            {
                if (disposing)
                {
                    if (_asynRequest != null)
                        _asynRequest.Abort();
                    if (_asynResponse != null)
                        _asynResponse.Close();
                }
            }
            isDisposable = true;
        }
        ~AsynHttpContext()
        {
            Dispose(false);
        }
    }
}





AsyncStream.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;


namespace AsyncHttpRequestDemo
{
    public class AsynStream
    {
        int _offset;
        /// <summary>
        /// 偏移量
        /// </summary>
        public int Offset
        {
            get { return _offset; }
            set { _offset = value; }
        }


        int _count;
        /// <summary>
        /// 读取次数
        /// </summary>
        public int Count
        {
            get { return _count; }
            set { _count = value; }
        }
        int _unreadLength;
        /// <summary>
        /// 没有读取的长度
        /// </summary>
        public int UnreadLength
        {
            get { return _unreadLength; }
            set { _unreadLength = value; }
        }
        public AsynStream(int offset, int count, Stream netStream)
        {
            _offset = offset;
            _count = count;
            _netStream = netStream;
        }
        public AsynStream(Stream netStream)
        {
            _netStream = netStream;
        }




        Stream _netStream;


        public Stream NetStream
        {
            get { return _netStream; }
            set { _netStream = value; }
        }


    }
}






调用:


 
  Action<string, Exception> OnResponseGet = new Action<string, Exception>((s, ex) =>
            {
                if (ex != null)
                {
                    string exInfo = ex.Message;
                }
                string ret = s;
            });
            try
            {
                string strRequestXml = "hello";
                int timeout = 15000;
                string contentType = "text/xml";
                string url = "http://192.168.110.191:8092/getcontentinfo/";
                UTF8Encoding encoding = new UTF8Encoding();
                byte[] data = encoding.GetBytes(strRequestXml);


                HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
                myHttpWebRequest.Timeout = timeout;
                myHttpWebRequest.Method = "POST";
                myHttpWebRequest.ContentType = contentType;
                myHttpWebRequest.ContentLength = data.Length;


                //if (headers != null && headers.Count > 0)
                //{
                //    foreach (var eachheader in headers)
                //    {
                //        myHttpWebRequest.Headers.Add(eachheader.Key, eachheader.Value);
                //    }
                //}


             
                
                AsynHttpContext asynContext = new AsynHttpContext(myHttpWebRequest);
                // string tranKey = TransactionManager<AsynHttpContext>.Instance.Register(asynContext);


                AysncHttpRequestHelperV2.Post(asynContext, data, new Action<AsynHttpContext, Exception>((httpContext, ex) =>
                {
                    try
                    {
                        //       TransactionManager<AsynHttpContext>.Instance.Unregister(tranKey);




                        if (ex != null)
                        {
                            //    _tracing.Error(ex, "Exception Occurs On AysncHttpRequestHelperV2 Post Request.");
                            OnResponseGet(null, ex);
                        }
                        else
                        {
                            string rspStr = Encoding.UTF8.GetString(httpContext.ResponseBytes);
                            //  _tracing.InfoFmt("Aysnc Get Response Content : {0}", rspStr);
                            OnResponseGet(rspStr, null);
                        }
                    }
                    catch (Exception ex2)
                    {
                        //  _tracing.ErrorFmt(ex2, "");
                        OnResponseGet(null, ex2);
                    }
                }));
            }


            catch (Exception ex)
            {
                // _tracing.Error(ex, "Exception Occurs On Aysnc Post Request.");
                OnResponseGet(null, ex);
            }


相关文章:

  • Flex开发流程设计器的经验之谈(2)
  • html5 涂鸦板
  • [IE编程] IE中使网页元素进入编辑模式
  • linux命令练习 笔记
  • [IE技巧] IE 中打开Office文件的设置
  • 配置系统未能初始化 错误的解决方案
  • [IE编程] IE中对网页进行截图的编程接口
  • c# 反射 遍历实体的所有字段,ObjectDumper类实现
  • Flex开发流程设计器的经验之谈(3)
  • 飞信分布式存储的结构
  • 使用Zoundry进行测试了下!
  • 使用HTML5制作游戏
  • [Web开发] IE 所有版本打包下载,网页兼容测试必备
  • c# LazyQueueT实现
  • Windows NT/2k/XP/Vista 管理员密码重置
  • [case10]使用RSQL实现端到端的动态查询
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Hibernate【inverse和cascade属性】知识要点
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Laravel5.4 Queues队列学习
  • Meteor的表单提交:Form
  • Vue小说阅读器(仿追书神器)
  • 反思总结然后整装待发
  • 关于字符编码你应该知道的事情
  • 经典排序算法及其 Java 实现
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 实战|智能家居行业移动应用性能分析
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 写代码的正确姿势
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (8)STL算法之替换
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (动态规划)5. 最长回文子串 java解决
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (一)appium-desktop定位元素原理
  • (一)Linux+Windows下安装ffmpeg
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • .htaccess配置常用技巧
  • .net 设置默认首页
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .NET开发不可不知、不可不用的辅助类(一)
  • .NET项目中存在多个web.config文件时的加载顺序
  • .net与java建立WebService再互相调用
  • :中兴通讯为何成功