内网自建speedtest测速网站

简介:#

内网网速测试,需要找个方便的解决方案。

一:作者#

 https://github.com/librespeed/speedtest

adolfintel/speedtest - Docker Image | Docker Hub

二:docker-compose.yaml#

复制代码
version: '3.3'
services:
    speedtest:
        image:adolfintel/speedtest
        container_name: speedtest
        restart: always
        
        environment:
            - TITLE=内网网速测试
            - MODE=standalone
            - TELEMETRY=true
            - ENABLE_ID_OBFUSCATION=true
            - PASSWORD=yourPasswordHere
            - WEBPORT=80
        ports:
            - '8081:80'
                  
复制代码

三:改造模板#

默认模板是英文的,要改一下,顺便把后台统计也加进去。

从github获取standalone.php,模板文件

改过以后是这样的

复制代码
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no" />
<meta charset="UTF-8" />
<link rel="shortcut icon" href="favicon.ico">
<script type="text/javascript" src="speedtest.js"></script>
<script type="text/javascript">
function I(i){return document.getElementById(i);}
//INITIALIZE SPEEDTEST
var s=new Speedtest(); //create speedtest object
<?php if(getenv("TELEMETRY")=="true"){ ?>
s.setParameter("telemetry_level","basic");
<?php } ?>
<?php if(getenv("DISABLE_IPINFO")=="true"){ ?>
s.setParameter("getIp_ispInfo",false);
<?php } ?>
<?php if(getenv("DISTANCE")){ ?>
s.setParameter("getIp_ispInfo_distance","<?=getenv("DISTANCE") ?>");
<?php } ?>

var meterBk=/Trident.*rv:(\d+\.\d+)/i.test(navigator.userAgent)?"#EAEAEA":"#80808040";
var dlColor="#6060AA",
    ulColor="#616161";
var progColor=meterBk;

//CODE FOR GAUGES
function drawMeter(c,amount,bk,fg,progress,prog){
    var ctx=c.getContext("2d");
    var dp=window.devicePixelRatio||1;
    var cw=c.clientWidth*dp, ch=c.clientHeight*dp;
    var sizScale=ch*0.0055;
    if(c.width==cw&&c.height==ch){
        ctx.clearRect(0,0,cw,ch);
    }else{
        c.width=cw;
        c.height=ch;
    }
    ctx.beginPath();
    ctx.strokeStyle=bk;
    ctx.lineWidth=12*sizScale;
    ctx.arc(c.width/2,c.height-58*sizScale,c.height/1.8-ctx.lineWidth,-Math.PI*1.1,Math.PI*0.1);
    ctx.stroke();
    ctx.beginPath();
    ctx.strokeStyle=fg;
    ctx.lineWidth=12*sizScale;
    ctx.arc(c.width/2,c.height-58*sizScale,c.height/1.8-ctx.lineWidth,-Math.PI*1.1,amount*Math.PI*1.2-Math.PI*1.1);
    ctx.stroke();
    if(typeof progress !== "undefined"){
        ctx.fillStyle=prog;
        ctx.fillRect(c.width*0.3,c.height-16*sizScale,c.width*0.4*progress,4*sizScale);
    }
}
function mbpsToAmount(s){
    return 1-(1/(Math.pow(1.3,Math.sqrt(s))));
}
function format(d){
    d=Number(d);
    if(d<10) return d.toFixed(2);
    if(d<100) return d.toFixed(1);
    return d.toFixed(0);
}

//UI CODE
var uiData=null;
function startStop(){
    if(s.getState()==3){
        //speedtest is running, abort
        s.abort();
        data=null;
        I("startStopBtn").className="";
        initUI();
    }else{
        //test is not running, begin
        I("startStopBtn").className="running";
        I("shareArea").style.display="none";
        s.onupdate=function(data){
            uiData=data;
        };
        s.onend=function(aborted){
            I("startStopBtn").className="";
            updateUI(true);
            if(!aborted){
                //if testId is present, show sharing panel, otherwise do nothing
                try{
                    var testId=uiData.testId;
                    if(testId!=null){
                        var shareURL=window.location.href.substring(0,window.location.href.lastIndexOf("/"))+"/results/?id="+testId;
                        I("resultsImg").src=shareURL;
                        I("resultsURL").value=shareURL;
                        I("testId").innerHTML=testId;
                        I("shareArea").style.display="";
                    }
                }catch(e){}
            }
        };
        s.start();
    }
}
//this function reads the data sent back by the test and updates the UI
function updateUI(forced){
    if(!forced&&s.getState()!=3) return;
    if(uiData==null) return;
    var status=uiData.testState;
    I("ip").textContent=uiData.clientIp;
    I("dlText").textContent=(status==1&&uiData.dlStatus==0)?"...":format(uiData.dlStatus);
    drawMeter(I("dlMeter"),mbpsToAmount(Number(uiData.dlStatus*(status==1?oscillate():1))),meterBk,dlColor,Number(uiData.dlProgress),progColor);
    I("ulText").textContent=(status==3&&uiData.ulStatus==0)?"...":format(uiData.ulStatus);
    drawMeter(I("ulMeter"),mbpsToAmount(Number(uiData.ulStatus*(status==3?oscillate():1))),meterBk,ulColor,Number(uiData.ulProgress),progColor);
    I("pingText").textContent=format(uiData.pingStatus);
    I("jitText").textContent=format(uiData.jitterStatus);
}
function oscillate(){
    return 1+0.02*Math.sin(Date.now()/100);
}
//update the UI every frame
window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||(function(callback,element){setTimeout(callback,1000/60);});
function frame(){
    requestAnimationFrame(frame);
    updateUI();
}
frame(); //start frame loop
//function to (re)initialize UI
function initUI(){
    drawMeter(I("dlMeter"),0,meterBk,dlColor,0);
    drawMeter(I("ulMeter"),0,meterBk,ulColor,0);
    I("dlText").textContent="";
    I("ulText").textContent="";
    I("pingText").textContent="";
    I("jitText").textContent="";
    I("ip").textContent="";
}
</script>
<style type="text/css">
    html,body{
        border:none; padding:0; margin:0;
        background:#FFFFFF;
        color:#202020;
    }
    body{
        text-align:center;
        font-family:"Roboto",sans-serif;
    }
    h1{
        color:#404040;
    }
    #startStopBtn{
        display:inline-block;
        margin:0 auto;
        color:#6060AA;
        background-color:rgba(0,0,0,0);
        border:0.15em solid #6060FF;
        border-radius:0.3em;
        transition:all 0.3s;
        box-sizing:border-box;
        width:8em; height:3em;
        line-height:2.7em;
        cursor:pointer;
        box-shadow: 0 0 0 rgba(0,0,0,0.1), inset 0 0 0 rgba(0,0,0,0.1);
    }
    #startStopBtn:hover{
        box-shadow: 0 0 2em rgba(0,0,0,0.1), inset 0 0 1em rgba(0,0,0,0.1);
    }
    #startStopBtn.running{
        background-color:#FF3030;
        border-color:#FF6060;
        color:#FFFFFF;
    }
    #startStopBtn:before{
        content:"开始测速";
    }
    #startStopBtn.running:before{
        content:"停止测速";
    }
    #test{
        margin-top:2em;
        margin-bottom:12em;
    }
    div.testArea{
        display:inline-block;
        width:16em;
        height:12.5em;
        position:relative;
        box-sizing:border-box;
    }
    div.testArea2{
        display:inline-block;
        width:14em;
        height:7em;
        position:relative;
        box-sizing:border-box;
        text-align:center;
    }
    div.testArea div.testName{
        position:absolute;
        top:0.1em; left:0;
        width:100%;
        font-size:1.4em;
        z-index:9;
    }
    div.testArea2 div.testName{
        display:block;
        text-align:center;
        font-size:1.4em;
    }
    div.testArea div.meterText{
        position:absolute;
        bottom:1.55em; left:0;
        width:100%;
        font-size:2.5em;
        z-index:9;
    }
    div.testArea2 div.meterText{
        display:inline-block;
        font-size:2.5em;
    }
    div.meterText:empty:before{
        content:"0.00";
    }
    div.testArea div.unit{
        position:absolute;
        bottom:2em; left:0;
        width:100%;
        z-index:9;
    }
    div.testArea2 div.unit{
        display:inline-block;
    }
    div.testArea canvas{
        position:absolute;
        top:0; left:0; width:100%; height:100%;
        z-index:1;
    }
    div.testGroup{
        display:block;
        margin: 0 auto;
    }
    #shareArea{
        width:95%;
        max-width:40em;
        margin:0 auto;
        margin-top:2em;
    }
    #shareArea > *{
        display:block;
        width:100%;
        height:auto;
        margin: 0.25em 0;
    }
    #privacyPolicy{
        position:fixed;
        top:2em;
        bottom:2em;
        left:2em;
        right:2em;
        overflow-y:auto;
        width:auto;
        height:auto;
        box-shadow:0 0 3em 1em #000000;
        z-index:999999;
        text-align:left;
        background-color:#FFFFFF;
        padding:1em;
    }
    a.privacy{
        text-align:center;
        font-size:0.8em;
        color:#808080;
        display:block;
    }
    @media all and (max-width:40em){
        body{
            font-size:0.8em;
        }
    }
</style>
<title><?= getenv('TITLE') ?: 'LibreSpeed Example' ?></title>
</head>
<body>
<h1><?= getenv('TITLE') ?: 'LibreSpeed Example' ?></h1>
<div id="testWrapper">
    <div id="startStopBtn" onclick="startStop()"></div><br/>
    <?php if(getenv("TELEMETRY")=="true"){ ?>
        <a class="privacy" href="/results/stats.php" >数据统计</a>
    <?php } ?>
    <div id="test">
        <div class="testGroup">
            <div class="testArea2">
                <div class="testName">连接延迟</div>
                <div id="pingText" class="meterText" style="color:#AA6060"></div>
                <div class="unit">ms</div>
            </div>
            <div class="testArea2">
                <div class="testName">连接抖动</div>
                <div id="jitText" class="meterText" style="color:#AA6060"></div>
                <div class="unit">ms</div>
            </div>
        </div>
        <div class="testGroup">
            <div class="testArea">
                <div class="testName">下载速度</div>
                <canvas id="dlMeter" class="meter"></canvas>
                <div id="dlText" class="meterText"></div>
                <div class="unit">Mbps</div>
            </div>
            <div class="testArea">
                <div class="testName">上传速度</div>
                <canvas id="ulMeter" class="meter"></canvas>
                <div id="ulText" class="meterText"></div>
                <div class="unit">Mbps</div>
            </div>
        </div>
        <div id="ipArea">
            <span id="ip"></span>
        </div>
        <div id="shareArea" style="display:none">
            <h3>分享结果</h3>
            <p>Test ID: <span id="testId"></span></p>
            <input type="text" value="" id="resultsURL" readonly="readonly" onclick="this.select();this.focus();this.select();document.execCommand('copy');alert('Link copied')"/>
            <img src="" id="resultsImg" />
        </div>
    </div>
</div>
<script type="text/javascript">setTimeout(function(){initUI()},100);</script>
</body>
</html>
View Code
复制代码

四:创建Dockerfile#

FROM adolfintel/speedtest
COPY standalone.php /speedtest/

只是替换模板文件而已。

五:数据持久化#

作者没介绍,但是在源码entrypoint.sh中找到了

mkdir -p /database/
chown www-data /database/

 容器内目录为: /database

六:全部改造#

 

复制代码
version: '3.3'
services:
    speedtest:
        build:
            context: .
            dockerfile: Dockerfile
        container_name: speedtest
        restart: always
        
        environment:
            - TITLE=内网网速测试
            - MODE=standalone
            - TELEMETRY=true
            - ENABLE_ID_OBFUSCATION=true
            - PASSWORD=yourPasswordHere
            - WEBPORT=80
        ports:
            - '8081:80'
        volumes:
          - ./database:/database
复制代码

 

七:愉快的玩耍吧#

删除了一些作者的东西,很不好意思,但是我们的内网没几个人能看懂。

作者:上官飞鸿

出处:https://www.cnblogs.com/jackadam/p/17552148.html

版权:本作品采用「知识共享-署名-非商业性-禁止演绎(CC-BY-NC-ND)」许可协议进行许可。

posted @   上官飞鸿  阅读(1622)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2018-07-13 selenium(七)webdriverwait,高级等待,替代sleep
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示