WebClient 下载超时

  /// <summary>
    /// Geovin Du geovindu 塗聚文  涂聚文
    /// </summary>
    public class NewWebClient : WebClient
    {
        private int _timeout;

        /// <summary>
        /// 超时时间(毫秒)
        /// </summary>
        public int Timeout
        {
            get
            {
                return _timeout;
            }
            set
            {
                _timeout = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public NewWebClient()
        {
            this._timeout = 60000;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeout"></param>
        public NewWebClient(int timeout)
        {
            this._timeout = timeout;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        protected override WebRequest GetWebRequest(Uri address)
        {
            //WebClient里上传下载的方法很多,但最终应该都是调用了这个方法
            HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
            request.Timeout = Timeout;
            request.ReadWriteTimeout = Timeout;
            return request;

        }
    }


    public class Calculagraph
    {
        /// <summary>
        /// 时间到事件
        /// </summary>
        public event TimeoutCaller TimeOver;

        /// <summary>
        /// 开始时间
        /// </summary>
        private DateTime _startTime;
        private TimeSpan _timeout = new TimeSpan(0, 0, 10);
        private bool _hasStarted = false;
        object _userdata;

        /// <summary>
        /// 计时器构造方法
        /// </summary>
        /// <param name="userdata">计时结束时回调的用户数据</param>
        public Calculagraph(object userdata)
        {
            TimeOver += new TimeoutCaller(OnTimeOver);
            _userdata = userdata;
        }

        /// <summary>
        /// 超时退出
        /// </summary>
        /// <param name="userdata"></param>
        public virtual void OnTimeOver(object userdata)
        {
            Stop();
        }

        /// <summary>
        /// 过期时间(秒)
        /// </summary>
        public int Timeout
        {
            get
            {
                return _timeout.Seconds;
            }
            set
            {
                if (value <= 0)
                    return;
                _timeout = new TimeSpan(0, 0, value);
            }
        }

        /// <summary>
        /// 是否已经开始计时
        /// </summary>
        public bool HasStarted
        {
            get
            {
                return _hasStarted;
            }
        }

        /// <summary>
        /// 开始计时
        /// </summary>
        public void Start()
        {
            Reset();
            _hasStarted = true;
            Thread th = new Thread(WaitCall);
            th.IsBackground = true;
            th.Start();
        }

        /// <summary>
        /// 重置
        /// </summary>
        public void Reset()
        {
            _startTime = DateTime.Now;
        }

        /// <summary>
        /// 停止计时
        /// </summary>
        public void Stop()
        {
            _hasStarted = false;
        }

        /// <summary>
        /// 检查是否过期
        /// </summary>
        /// <returns></returns>
        private bool checkTimeout()
        {
            return (DateTime.Now - _startTime).Seconds >= Timeout;
        }

        private void WaitCall()
        {
            try
            {
                //循环检测是否过期
                while (_hasStarted && !checkTimeout())
                {
                    Thread.Sleep(1000);
                }
                if (TimeOver != null)
                    TimeOver(_userdata);
            }
            catch (Exception)
            {
                Stop();
            }
        }
    }

    /// <summary>
    /// 过期时回调委托
    /// </summary>
    /// <param name="userdata"></param>
    public delegate void TimeoutCaller(object userdata);

    /// <summary>
    /// 
    /// </summary>
    public class DuWebClient : WebClient
    {

        private Calculagraph _timer;
        private int _timeOut = 10;

        /// <summary>
        /// 过期时间
        /// </summary>
        public int Timeout
        {
            get
            {
                return _timeOut;
            }
            set
            {
                if (value <= 0)
                    _timeOut = 10;
                _timeOut = value;
            }
        }

                /// <summary>
        /// 
        /// </summary>
        public DuWebClient()
        {
            this._timeOut = 60000;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeout"></param>
        public DuWebClient(int timeout)
        {
            this._timeOut = timeout;
        }


        /// <summary>
        /// 重写GetWebRequest,添加WebRequest对象超时时间
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        protected override WebRequest GetWebRequest(Uri address)
        {
            HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
            request.Timeout = 1000 * Timeout;
            request.ReadWriteTimeout = 1000 * Timeout;
            return request;
        }

        /// <summary>
        /// 带过期计时的下载
        /// </summary>
        public void DownloadFileAsyncWithTimeout(Uri address, string fileName, object userToken)
        {
            if (_timer == null)
            {
                _timer = new Calculagraph(this);
                _timer.Timeout = Timeout;
                _timer.TimeOver += new TimeoutCaller(_timer_TimeOver);
                this.DownloadProgressChanged += new DownloadProgressChangedEventHandler(CNNWebClient_DownloadProgressChanged);
            }

            DownloadFileAsync(address, fileName, userToken);
            _timer.Start();
        }

        /// <summary>
        /// WebClient下载过程事件,接收到数据时引发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CNNWebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            _timer.Reset();//重置计时器
        }

        /// <summary>
        /// 计时器过期
        /// </summary>
        /// <param name="userdata"></param>
        void _timer_TimeOver(object userdata)
        {
            this.CancelAsync();//取消下载
        }
    }

  

string url = "http://www.dusystem.com/DuBooket/JwBookTest.ashx?DuQuery=" + projectid; //&jsonpCallback=?
                    
                    context.Response.AddHeader("Access-Control-Allow-Origin", "http://intranet.lukfook.com.hk/");
                    context.Response.ContentType = "application/json ;charset=utf-8";
                   
                    //1
                    //WebClient wc = new WebClient();
                    //wc.Headers["User-Agent"] = "blah";
                    //wc.Encoding = System.Text.Encoding.UTF8;//定义对象语言  Geovin Du 涂聚文
                    //byte[] btWeb = wc.DownloadData(url);
                    
                    //2
                    //NewWebClient wc = new NewWebClient(30 * 60 * 1000);
                    //byte[] btWeb = wc.DownloadData(url);
                    //wc.Headers["User-Agent"] = "blah";
                    //wc.Encoding = System.Text.Encoding.UTF8;
                    //json = Encoding.GetEncoding("GB2312").GetString(btWeb);

                    //3
                    DuWebClient wc = new DuWebClient(30 * 60 * 1000);
                    byte[] btWeb = wc.DownloadData(url);
                    wc.Headers["User-Agent"] = "blah";
                    wc.Encoding = System.Text.Encoding.UTF8;

                    json = System.Text.Encoding.UTF8.GetString(btWeb);
                    context.Response.ContentType = "text/plain";
                    context.Response.Write(json);

  

 

safari 下載亂碼問題
          /*
                 * safari相对比较变态, filename部分只能使用utf-8的原始字节,而http header 必须使用单字节编码的字符串, 因此需要将原始内容重新构造为iso-8859-1单字节编码的字符串,即:new String(filename.getBytes("UTF-8"),"ISO8859-1") 
                 * 编码方式  |  测试通过的浏览器
                new String(filename.getBytes("UTF-8"),"ISO8859-1")
前端-后台   base_name.getBytes("ISO-8859-1"),"UTF-8")
后台-前端   base_name.getBytes("GB2312"),"ISO-8859-1")
RFC2231 filename* |   ie9 ,chrome17 , opera11,firefox11

iso-8859-1 (utf-8):  |  chrome,opera,firefox,safari

url-encode(utf-8)  |    ie6+ (文件名必须带扩展名), chrome\opera(%2B 加号不识别)


因此兼容规则设置为  ie: urlEncode  , opera\firefox : filename*,  safari\chrome: iso-8859-1 比较合适
                 * 各浏览器支持的对应编码格式为: 

1.  IE浏览器,采用URLEncoder编码 
2.  Opera浏览器,采用filename*方式 
3.  Safari浏览器,采用ISO编码的中文输出 
4.  Chrome浏览器,采用Base64编码或ISO编码的中文输出 
5.  FireFox浏览器,采用Base64或filename*或ISO编码的中文输出 


new_filename = URLEncoder.encode(filename, "UTF8");  
// 如果没有UA,则默认使用IE的方式进行编码,因为毕竟IE还是占多数的  
rtn = "filename=\"" + new_filename + "\"";  
if (userAgent != null)  
{  
     userAgent = userAgent.toLowerCase();  
      // IE浏览器,只能采用URLEncoder编码  
     if (userAgent.indexOf("msie") != -1)  
    {  
        rtn = "filename=\"" + new_filename + "\"";  
    }  
     // Opera浏览器只能采用filename*  
     else if (userAgent.indexOf("opera") != -1)  
     {  
        rtn = "filename*=UTF-8''" + new_filename;  
    }  
    // Safari浏览器,只能采用ISO编码的中文输出  
      else if (userAgent.indexOf("safari") != -1 )  
      {  
          rtn = "filename=\"" + new String(filename.getBytes("UTF-8"),"ISO8859-1") + "\"";   //java
      }  
      // Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出  
      else if (userAgent.indexOf("applewebkit") != -1 )  
       {  
         new_filename = MimeUtility.encodeText(filename, "UTF8", "B");  
          rtn = "filename=\"" + new_filename + "\"";  
       }  
      // FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出  
       else if (userAgent.indexOf("mozilla") != -1)  
       {  
          rtn = "filename*=UTF-8''" + new_filename;  
      }  
   }  

                 
                 
                 
                 */

  

https://www.codeproject.com/articles/1088703/how-to-detect-browsers-in-asp-net-with-browser-fil
Chrome 47

Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36

Firefox 43

Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/43.0

Safari 8

Mozilla/5.0 (iPhone; CPU iPhone OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H321 Safari/600.1.4

IE 11

Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko

Edge

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240

Opera

Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14

Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36 OPR/34.0.2036.25

Silk 2

Mozilla/5.0 (Linux; U; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/2.1 Safari/535.19 Silk-Accelerated=true

Maxthon 4

Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.1.5000 Chrome/30.0.1599.101 Safari/537.36

SeaMonkey 8

Mozilla/5.0 (Windows; U; Windows NT 10.0; WOW64; rv:1.8.0.7) Gecko/20110321 MultiZilla/4.33.2.6a SeaMonkey/8.6.55

public bool IsMacOS(string userAgent)
{
    var osInfo = userAgent.Split(new Char[] { '(', ')' })[1];
    return osInfo.Contains("Mac_PowerPC") || osInfo.Contains("Macintosh");
}

    HttpBrowserCapabilities moo = HttpContext.Current.Request.Browser;

    StringBuilder sb = new StringBuilder();

    sb.Append("<p>Browser Capabilities:</p>");
    sb.Append("Type = " + moo.Type + "<br>");
    sb.Append("Name = " + moo.Browser + "<br>");
    sb.Append("Version = " + moo.Version + "<br>");
    sb.Append("Major Version = " + moo.MajorVersion + "<br>");
    sb.Append("Minor Version = " + moo.MinorVersion + "<br>");
    sb.Append("Platform = " + moo.Platform + "<br>");
    sb.Append("Is Beta = " + moo.Beta + "<br>");
    sb.Append("Is Crawler = " + moo.Crawler + "<br>");
    sb.Append("Is AOL = " + moo.AOL + "<br>");
    sb.Append("Is Win16 = " + moo.Win16 + "<br>");
    sb.Append("Is Win32 = " + moo.Win32 + "<br>");
    sb.Append("Supports Frames = " + moo.Frames + "<br>");
    sb.Append("Supports Tables = " + moo.Tables + "<br>");
    sb.Append("Supports Cookies = " + moo.Cookies + "<br>");
    sb.Append("Supports VB Script = " + moo.VBScript + "<br>");       
    sb.Append("Supports ActiveX Controls = " + moo.ActiveXControls + "<br>");
    sb.Append("CDF = " + moo.CDF + "<br>");
 /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private string UtfToIso(string message)
        {
            Encoding iso = Encoding.GetEncoding("ISO-8859-1");
            Encoding utf8 = Encoding.UTF8;
            byte[] utfBytes = utf8.GetBytes(message);
            byte[] isoBytes = Encoding.Convert(utf8, iso, utfBytes);
            string msg = iso.GetString(isoBytes);
            return msg;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private string IsoDecode(string message)
        {
            string result = "";

            Encoding iso = Encoding.GetEncoding("iso-8859-1");
            Encoding utf8 = Encoding.UTF8;
            byte[] isoBytes = iso.GetBytes(message);
            byte[] utf8Bytes = Encoding.Convert(iso, utf8, isoBytes);
            result = utf8.GetString(utf8Bytes);
            return result;
        }

  

posted @ 2021-11-17 17:28  ®Geovin Du Dream Park™  阅读(112)  评论(0)    收藏  举报