• [置顶] 腾讯朋友网网络报卡



    腾讯朋友网网络报卡

    原理分析:

    最近看腾讯朋友网网络报卡,发现腾讯的网路服务器有很多,当用户连接慢时,页面会请求不同是服务器,每个服务器相同路径下都存储有同一张图片,根据加载图片的时间长短来选择服务器,以便达到用户访问最适合自己,时间最短的服务器。

    实例分析:

    1.记录当前页面开始时间time1

    2.循环请求每个服务器下面的图片,记录图片开始请求时间和结束时间,

    3.根据结束时间和请求时间差,选择请求时间最短的服务器

    文档构建

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
        <title>小诊所 - 朋友网(腾讯朋友)</title>
    
        <script type="text/javascript">
            var startLoad=+new Date();
        </script>
    
        <style type="text/css">
            *{margin:0;padding:0;}
            body{font:13px/1.8em Verdana,Helvetioa,Arial,sans-serif;background-color:#D2D1D0;color:#444444;}
            a{ color:#3366CC;text-decoration:none;}
            a:hover{color:#117CFF;text-decoration:underline;}
            .wrapper{position:relative;padding:1px;650px;margin:20px auto 0;border:solid #bbbbbb 1px;background-color:#ffffff;box-shadow:1px 1px 2px rgba(0,0,0,0.3);}
            .wrapper .wrapper-entry{background-color:#f4f4f4;}
            .c-title{margin:0 5px;padding:8px 10px;border-bottom:dotted #E0E0E0 1px;line-height:1.2em;font-size:18px;font-weight:bold;font-family:'Microsoft YaHei';}
            .c-box{padding:15px;}
            .c-foot{padding:5px 15px;font-size:12px;border-top:solid #e5e5e5 1px;background-color:#EFEFEF;}
            .c-btn-box,.c-rs{padding:0 5px;margin:15px 0;}
            .c-btn,.c-btn:visited{
                font-size:13px;
                background-color:#85AE09;
                display:inline-block;
                padding:5px 10px 6px;
                color:#FFF;
                text-decoration:none;
                border-radius:6px;
                box-shadow:0 1px 3px rgba(0,0,0.0.6);
                border-bottom:1px solid rgba(0,0,0,0.25);
                position:relative;
                cursor:pointer;
            }
            .c-btn:hover{text-decoration:none;background-color:#111;color:#fff;background-color:#7A9F09;}
            .c-btn:active{top:1px;};
            .c-rs{color:#717171;_height:5.4em;min-height:5.4em;line-height:1.8em;}
            .c-rs .title{font-size:14px;font-weight:bold;}
            .success{color:#81A809;}
            .error{color:#BF0000;}
            .c-over{position:absolute;text-align:center;250px;background:#fff;border:solid #ccc 1px;}
        </style>
    </head>
    <body>
        <div class="wrapper">
            <div class="wrapper-entry">
                <h1 class="c-title">
                    朋友网小诊所</h1>
                <div class="c-box">
                    <p>
                        为了让您每天都能顺畅地浏览朋友网,您可以使用小诊所进行诊断分析。</p>
                    <p>
                        如果小诊所没有解决您的问题,您还可以下载 <a href="http://guanjia.qq.com/" target="_blank" title="QQ电脑管家">
                            QQ电脑管家</a>、<a href="http://imgcache.qq.com/tools/emu/checknetwork.signed.zip" title="QQ空间网络状况分析工具">QQ空间网络状况分析工具</a>进一步进行诊断。</p>
                    <div class="c-btn-box">
                        <a href="javascript:void(0);" title="点击开始诊断" class="c-btn" id="J_Start">开始诊断</a>
                    </div>
                    <div class="c-rs" id="J_Result" style="display: none;">
                        <div id="J_RS_ISP">
                        </div>
                        <div id="J_RS_CACHE">
                        </div>
                    </div>
                </div>
                <div class="c-foot">
                    <a href="http://www.pengyou.com" title="返回朋友网">«返回朋友网</a>
                </div>
                <!-- <div class="c-over"><a href="#" title="" class="btn-over">诊断完成,返回朋友网</a></div> END-->
            </div>
        </div>
        <div id="Console">
        </div>
    
        <script type="text/javascript">
        Clinic.init({btn:'J_Start'});
        $.speed.set(1,67,3,+new Date(),startLoad);
        $.ping('/clinic/');
        </script>
    
    </body>
    </html>

    公用JS函数:

    这些函数有的是跟下面的请求函数定制的,所以大家能看懂大概什么意思,做了哪些事就行了。

    function $(d){var ele=typeof(d)==='string'?document.getElementById(d):d;return ele;}
            String.prototype.trim=function(r){return this.replace(r||/^s+|s+$/g,"");};
            $.cookie=function(name,value,options){
                if(typeof value!='undefined'){
                    options=options||{'domain':'pengyou.com',path:'/'};
                    if(value===null){
                        value='';
                        options.expires=-1;
                    }
                    var expires='',date;
                    if(options.expires&&(typeof options.expires=="number"||options.expires.toUTCString)){
                        if(typeof options.expires=="number"){
                            date=new Date();
                            date.setTime(date.getTime()+(options.expires*24*60*60*1000));
                        }else{
                            date=options.expires;
                        }
                        expirex=';expires='+date.toUTCString();
                    }
                    var path=options.path?';path='+(options.path):'',domain=';domain='+(options.domain?(options.domain):'pengyou.com'),
                    secure=options.secure?';secure':'';
                    document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');
                }else{
                    var cookieValue='';
                    if(document.cookie){
                        var cookies=document.cookie.split(';'),cookie;
                        for(var i=0,l=cookies.length;i<l;i++){
                            cookie=cookies[i].trim();
                            if(cookie.substring(0,name.length+1)==(name+"=")){
                                cookieValue=decodeURIComponent(cookie.substring(name,length+1));
                                break;
                            }
                        }
                    }
                    return cookieValue;
                }
           }
           function pgvGetUserInfo(){
                var m=document.cookie.match(/(^|;|s)*pvid=([^;]*)(;|$)/);
                if(m){
                    pvid=m[2]
                }else{
                    var pvid=(Math.round(Math.random()*2147483647)*(new Date().getUTCMilliseconds()))%10000000000;
                    if((/^http://((.*?).|)pengyou.com/.*/i).test(location.href)){
                        document.cookie="pvid="+pvid+";path=/;domain=pengyou.com;expires=Sun, 18 Jan 2038 00:00:00 GMT;";
                    }else{
                        document.cookie="pvid="+pvid+";path=/:domain=qq.com;expires=Sun, 18 Jan 2038 00:00:00 GMT;";
                    }
                }
                return "&pvid="+pvid;
           }
           $.ping=function(urlx,domainx,rurlx,rdomainx){
                domainx=domainx||'app.xiaoyou.com';
                rurlx=rurlx||'-';
                rdomainx=rdomainx||'xiaoyou.qq.com';
                var Url;
                if((/^http://((.*?).|)pengyou.com/.*/i).test(location.href)){
                    Url="http://pingfor.pengyou.com";
                }else{
                    Url="http://pingfor.qq.com";
                }
                Url+="/pingd?dm="+domainx+"&url="+urlx+"&tt=-"+"&rdm="+rdomainx+"&rurl"+escape(rurlx)+pgvGetUserInfo()+"&scr=-&scl=-&lang=-&java=1&cc=-&pf=-&tz=-8&ct=-&vs=3.3"
                new Image().src=Url+"&emu="+Math.random();
           }
           $.speed={set:function(f2,f3,id,value,basetime){ 
                var key=f2+'_'+f3,startTime,endTime,speed,loadTimes={};
                if(!this[key]){
                    this[key]=[];
                }
                startTime=basetime||this[key][0]||startLoad;
                endTime=value||(+new Date());
                if(id!==0&&startTime!==undefined&&startTime!==null){
                    speed=endTime-startTime;
                }else if(id===0){
                    speed=endTime-1+1;
                }
                if(speed!==undefined){
                    this[key][id]=speed;
                }
               },
               send:function(f2,f3,setting){
                setting=setting||{};
                var key=f2+'_'+f3,data=this[key],_arr=[];
                if(!data||data.length<=0){ return false; }
                for(var i=1;i<data.length;i++){
                    if(data[i]){
                        _arr.push(i+'='+data[i]);
                    }
                }
                var flags=[[f2,f3]],urls=[],copyTo=setting.copyTo;
                if(copyTo){
                    if($.isArray(copyTo[0])){
                        flags=flags.concat(copyTo);
                    }else{
                        flags.push(copyTo);
                    }
                }
                var i=0,cur,times=_arr.join('&');
                for(;cur=flags[i++];){
                    urls.push("http://isdspeed.qq.com/cgi-bin/r.cgi?flag1=164&flag2="+cur[0]+"&flag3="+cur[1]+"&"+times);
                }
                var i=0,l=urls.length;
                for(;i<l;++i){
                    var imgSendTimePoint=new Image();
                    imgSendTimePoint.src=urls[i];
                }
                this[key]=[];
               }};
               //237/240行传入的参数:800160,1,51
               $.returncode=function(flag1,flag2,flag3,sampling,delay){
                    sampling=sampling||100;                                 //计算sampling值,每次计算的值可能不一样
                    if(sampling<100){
                        if(Math.floor(Math.random()*100)>=sampling){ return; }      //随机数大于小于100的sampling时返回,这里可能是要求sampling不能太小(比如:1,2,3...,应该尽可能的大一点,猜测可能是QQ服务器这样要求的)
                    }
                    sampling=Math.ceil(100/sampling);                       //取大于等于参数(100/sampling)的最小整数
                    delay=delay||0;                                         //判断赋值delay
                    flag2=flag2||1;                                         //判断赋值flag2
                    var url="http://isdspeed.qq.com/cgi-bin/v.cgi?flag1="+flag1+"&flag2="+flag2+"&1="+sampling+"&2="+delay;     //拼接URL
                    if(flag3){
                        url+="&flag3="+flag3;
                    }
                    var imgSend=new Image();                                //初始化Image对象
                    setTimeout(function(){imgSend.src=url},0);              //指定Image对象的src
               }
               function ctest(msg){                                         //向层Console里面添加指定内容的div
                    var b=document.createElement('div');
                    b.innerHTML=msg;
                    document.getElementById("Console").appendChild(b);
               }

    请求函数Clinic解析:

    Clinic.ISP={
                    key:{                       //设置key属性,里面的参数固定
                        fast:'FAST',
                        old:'OLD',
                        store:'_store',
                        isstart:'_isstart'
                    },
                    _timeout:10000,             //设置超时时间
                    test:function(callback){    //开始与服务器的测速
                        if(this[this.key.isstart]){ return false; }     //this[this.key.isstart]==true时,返回相当于lock(object)
                        this[this.key.isstart]=true;                    //设置this[this.key.isstart]=true表示开始执行
                        var that=this;                                  //赋值that=this
                        var dms=this.getDomains(),                      //获取子域网址
                            startTime=+new Date(),
                            fn=function(img){
                                if(dms.length){
                                    setTimeout(function(){
                                        that.request(dms.shift(),{complate:fn});    //执行request函数,传入子域对象{domain:'ctc.'+'qzonestyle.gtimg.cn',isp:'ctc'}和{complate:fn} fn指当前函数,这样函数内部在执行fn相当于递归
                                    },0);
                                }else{
                                    that.fix(callback,{                             //全部子域执行完成后执行提示是否返回朋友网
                                        start:startTime,
                                        end:+new Date()
                                    });
                                }
                            };
                            this._showMsg('正在为您选择更快的服务器,请耐心等候。');
                            fn();                                                   //开始执行fn函数
                    },
                    fix:function(success,setting){                                  //全部子域执行完成后执行的函数,success->函数,setting->{start:startTime,end:+new Date()}
                        setting=setting||{};                                        //初始化setting
                        var fast=this[this.key.fast];                               //获取this.key.fast对象
                        if(fast){                                                   //如果fast对象存在
                            success&&success(fast);                                 //执行传进来的函数:fn/callback
                            var old={                                               //初始化old对象
                                isp:this.get(),
                                cost:null
                            };
                            this[this.key.old]=old;                                 //本地存储old对象
                            $.cookie('ptisp',fast.isp,{expires:1,path:'/'});        //本地cookie存储参数:'ptisp',子域地址:'ctc.qzonestyle.gtimg.cn',{expires:1,path:'/'}
                            this._statistic(old,fast,{                              //执行_statistic函数参数分别是:old,fast,{start:setting.start,end:setting.end}
                                start:setting.start,
                                end:setting.end
                            });
                            this._showMsg('已经为您选择了更快的服务器','success');  //提示正在测速
                            $.returncode(800160,1,51);                              //执行returncode函数请求数据
                        }else{
                            this._showMsg('对不起,似乎您的电脑掉线了,选择服务器操作无法完成。','error');  //判断fast如果不存在则可能断网
                            $.returncode(800160,1,51);                              //执行returncode函数请求数据
                        }
                        this.rest();                                                //初始化本地数据
                    },
                    get:function(){                                                 //获取本地cookie存储的子域地址
                        var isp=$.cookie('ptisp');
                        return isp;
                    },
                    //传入子域对象{domain:'ctc.'+'qzonestyle.gtimg.cn',isp:'ctc'}和{complate:fn} 
                    request:function(domainInfo,config){
                        var _timeout=this._timeout;                                 //设置超时时间
                        config=config||{};                                          //判断赋值config
                        this._showNowcheck(domainInfo);                             //显示请求子域提示信息
                        var src='http://'+domainInfo.domain+'/qzonestyle/xiaoyou_portal_v1/img/logo_qbar_a0a48.gif';        //不同域请求的相同的图片 PS:这里是正题的开始
                        var img=new Image(),                                        //初始化Image对象
                            start=+new Date(),                                      //初始化启动时间
                            that=this;
                        var timer,timeStart=+new Date();
                        img.onload=function(){                                      //设置Image开始加载事件
                            var end=+new Date();                                    //初始化结束时间
                            var cost=end-start;                                     //初始化时间差
                            this.onload=this.onerror=null;                          //清除Image对象的onload,onerror事件
                            clearTimeout(timer);                                    //清除定时器
                            that._timeout=Math.min(that._timeout,cost);             //比较超时时间和加载结束时间,返回相对小的值
                            config.complate&&config.complate(this);                 //执行传过来的函数fn
                            var rs={                                                //初始化re对象包括:isp->子域,domain->子域地址,error->是否出错,cost->加载时间差,start->开始时间,end->加载完成时间
                                isp:domainInfo.isp,
                                domain:domainInfo.domain,
                                error:0,
                                cost:cost,
                                start:start,
                                end:end
                            };
                            that._saveResult(rs);                                   //保存rs对象
                        };
                        img.onerror=function(d){                                    //设置Image加载出错事件
                            this.onload=this.onerror=null;                          //清除Image对象的onload,onerror事件
                            clearTimeout(timer);                                    //清除定时器
                            config.complate&&config.complate(this);                 //执行传过来的函数fn
                            var rs={                                                //初始化rs对象
                                isp:domainInfo.isp,
                                domain:domainInfo.domain,
                                error:d&&d.timeout?'timeout':'onerror'
                            };
                            that._saveResult(rs);
                        };
                        timer=setTimeout(function(){
                            img.onerror({timeout:true});
                        },_timeout+300);
                        src=src+(src.indexOf('?')===-1?'?':'&')+'_='+(+new Date())+'&_='+Math.random();
                        img.src=src;
                    },
                    _saveResult:function(data){                                     //赋值this.key.store,this.key.fast
                        var key=this.key.store;
                        this[key]=this[key]||[];
                        if(!data.error){                                            //如果error=0时,如果data.cost存在赋值this.key.fast
                            this[key].push(data);
                            var keyFast=this.key.fast,
                                fast=this[keyFast];
                            if(data.cost){
                                if(!fast||data.cost<fast.cost){                     //当this.key.fast对象存在时,如果新的服务器请求时间少于this.key.fast对象存储的时间,则替换
                                    this[keyFast]=data;
                                }
                            }
                        }
                    },
                    _getResult:function(){
                        var key='_rsstore';
                        return this[key];
                    },
                    getIsps:function(){ var l=['ctc','cnc','edu','cn','cm','os','']; return l;},        //返回子域前缀数组
                    getHosts:function(){ var h=['qzonestyle.gtimg.cn'];return h;},                      //返回网站网址数组
                    getDomains:function(){                                                              //返回组合子域与网站网址后的网站网址
                        var isps=this.getIsps(),                                                        //获取子域前缀数组
                            hosts=this.getHosts(),                                                      //获取网站网址数组
                            sr=[];                                                                      //组合后的网站网址
                        while(hosts.length>0){
                            var i=0,l=isps.length,cur;
                            var h=hosts.shift();                                                        //去除第一个数组对象,并将其从数组中删除
                            for(;i<l;i++){
                                cur=isps[i];
                                sr.push({                                                               //添加对象到数组中,组合后的数组对象为:{domain:'ctc'+'qzonestyle.gtimg.cn',isp:'ctc'}
                                    domain:(cur?cur+'.':'')+h,
                                    isp:cur
                                });
                            }
                        }
                        return sr;
                    },
                    rest:function(){                                                                    //重置对象
                        this._timeout=10000;
                        this[this.key.fast]=null;
                        this[this.key.old]=null;
                        this[this.key.store]=null;
                        this[this.key.isstart]=null;
                    },
                    _showMsg:function(msg,type){                                                        //显示提示信息,不过多介绍了,大家看看就应该能懂
                        var box=$('J_RS_ISP');
                        if(box){
                            if(type==='success'){
                                msg='u221A '+msg;     //√
                            }else if(type==='error'){
                                msg='u00D7 '+msg;     //×
                            }
                            box.className=type||'';
                            box.innerHTML=msg;
                        }
                    },
                    _showNowcheck:function(info){                                                       //显示请求子域提示信息
                        $('J_Result').style.display='';
                        var box=$('J_RS_ISP'),
                            spid='J_RS_ISP_DETAIL',
                            sp=$(spid);
                        if(!sp){
                            sp=document.createElement('p');
                            sp.setAttribute('id',spid);
                            box.appendChild(sp);
                        }
                        sp.innerHTML=' '+info.domain;
                    },
                    _statistic:function(old,now,pay){
                        old.cost&&$.speed.set(1,67,1,old.end,old.start);
                        now.cost&&$.speed.set(1,67,2,now.end,now.start);
                        pay.end&&$.speed.set(1,67,4,pay.end,pay.start);
                        $.speed.send(1,67);
                        var ispf1={ctc:800152,cnc:800153,edu:800154,cn:800155,cm:800156,os:800157,v6:800158};
                        var ispid={ctc:51,cnc:52,edu:53,cn:54,cm:55,os:56,v6:57};
                        var ispf2=old.isp===now.isp?1:2;
                        ispf1=ispf1[old.isp]||8800159;
                        ispid=ispid[now.isp]||58;
                        $.returncode(ispf1,ispf2,ispid);
                    }
               };
               Clinic.Cache={                                                                       //指定Clinic对象Cache事件,清除缓存
                    clear:function(){
                        
                    }
               };

    效果展示:

    结语:

    希望有朝一日能把腾讯网站上的好东东都学会,如果能弄来腾讯的数据库什么的最好了 学习学习 偷笑


  • 相关阅读:
    python-super方法
    python--mixin
    python中将输出写入文件
    一致性hash算法
    mysql之触发器trigger
    python内置函数
    python3.5+Django2.2+pymysql+mysql
    File "D:PythonPython37-32libsite-packagesdjangoviewsdebug.py", line 332, in get_traceback_html   t = DEBUG_ENGINE.from_string(fh.read())
    RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to po
    python:面向对象
  • 原文地址:https://www.cnblogs.com/memaxiaofeng/p/3275472.html
Copyright © 2020-2023  润新知