Skip to content

Commit

Permalink
Add MTR Test
Browse files Browse the repository at this point in the history
  • Loading branch information
jason5ng32 committed Jan 27, 2024
1 parent d3d26eb commit 549146e
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 8 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ Notes: You can use my demo, but please don't use it for commercial purposes. If
* 🚦 **Availability Check**: Tests the accessibility of various websites, such as Google, GitHub, YouTube, ChatGPT, and others.
* 🚥 **WebRTC Detection**: Identifies the IP address used during WebRTC connections.
* 🛑 **DNS Leak Test**: Shows DNS endpoint data to evaluate the risk of DNS leaks when using VPNs or proxies.
* 🚀 **Speed Test**:Test your network speed with edge networks.
* 🌐 **Global Latency Test**: Performe lantency tests on servers located in different regions around the world.
* 📡 **MTR Test**: Perform MTR tests on servers located in different regions around the world.
* 🌗 **Dark Mode**: Automatically toggles between dark and daylight modes based on system settings, with an option for manual switching.
* 📱 **Minimalist Mode**: A mobile-optimized mode that shortens page length for quick access to essential information..
* 🔍 **Search IP Information**: Provides a tool for querying information about any IP address.
* 📲 **PWA Supported**:Can be added as a desktop app on your phone as well as a Chrome app on your computer.
* 🚀 **Speed Test**:Test your network speed with edge networks.
* 🌐 **Global Latency Test**: Performe lantency test on servers located in different regions around the world.
* ⌨️ **Keyboard Shortcuts**: Supports keyboard shortcuts for all functions, press `?` to view the shortcut list.
* 🌍 Based on availability test results, it indicates whether global internet access is currently feasible.
* 🇺🇸🇨🇳 English and Chinese supported.
Expand Down
5 changes: 3 additions & 2 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@
* 🚦 **可用性检测**:检测一些网站的可用性:Google, Github, Youtube, 网易, 百度等
* 🚥 **WebRTC 检测**:查看使用 WebRTC 连接时使用的 IP
* 🛑 **DNS 泄露检测**:查看 DNS 出口信息,以便查看在 VPN/代理的情况下,是否存在 DNS 泄露隐私的风险
* 🚀 **网速测试**:利用边缘网络进行网速测试
* 🌐 **全球延迟测试**:从分布在全球的多个服务器进行延迟测试,了解你与全球网络的连接速度
* 📡 **MTR 测试**:从分布在全球的多个服务器进行 MTR 测试,了解你与全球的连接路径
* 🌗 **暗黑模式**:根据系统设置自动切换暗黑/白天模式,也可以手动切换
* 📱 **简约模式**:为移动版提供的专门模式,缩短页面长度,快速查看最重要的信息
* 🔍 **查任意 IP 信息**:可以通过小工具查询任意 IP 的信息
* 📲 **支持 PWA**:可以添加为手机桌面应用以及电脑里的 Chrome 应用
* 🚀 **网速测试**:利用边缘网络进行网速测试
* 🌐 **全球延迟测试**:从分布在全球的多个服务器进行延迟测试,了解你与全球网络的连接速度
* ⌨️ **支持快捷键**:可以随时输入 `?` 查看快捷键菜单
* 🌍 根据可用性检测结果,返回目前是否可以访问全世界网络的提示
* 🇺🇸 🇨🇳 支持中文和英文
Expand Down
3 changes: 3 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<DNSLeaks ref="dnsLeaksRef" />
<SpeedTest ref="speedTestRef" />
<GlobalLatency ref="globalLatencyRef" />
<MTRtest ref="mtrtestRef" />
<QueryIP ref="queryIPRef" />
<HelpModal ref="helpModalRef" />
<!-- Info Mask BTN-->
Expand All @@ -44,6 +45,7 @@ import WebRTC from './components/webrtc.vue'
import DNSLeaks from './components/dnsleaks.vue'
import SpeedTest from './components/speedtest.vue'
import GlobalLatency from './components/globallatency.vue'
import MTRtest from './components/mtrtest.vue'
import Footer from './components/footer.vue'
import QueryIP from './components/queryip.vue'
import HelpModal from './components/help.vue'
Expand Down Expand Up @@ -82,6 +84,7 @@ export default {
DNSLeaks,
SpeedTest,
GlobalLatency,
MTRtest,
Footer,
QueryIP,
HelpModal,
Expand Down
2 changes: 1 addition & 1 deletion src/components/globallatency.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<p>{{ $t('pingtest.Note') }}</p>
</div>
<div class="row">
<div class="col-12">
<div class="col-12 mb-3">
<div class="card jn-card" :class="{ 'dark-mode dark-mode-border': isDarkMode }">
<div class="card-body">
<!-- Dropdown for IP Selection -->
Expand Down
230 changes: 230 additions & 0 deletions src/components/mtrtest.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
<template>
<!-- mtr Test -->
<div class="mtr-test-section mb-4">
<div class="jn-title2">
<h2 id="MTRTest" :class="{ 'mobile-h2': isMobile }">📡 {{ $t('mtrtest.Title') }}</h2>

</div>
<div class="text-secondary">
<p>{{ $t('mtrtest.Note') }}</p>
</div>
<div class="row">
<div class="col-12 mb-3">
<div class="card jn-card" :class="{ 'dark-mode dark-mode-border': isDarkMode }">
<div class="card-body">
<!-- Dropdown for IP Selection -->
<div class="row mt-3 mb-3 align-items-center justify-content-center">
<div class="col-12 col-md-auto">
<label for="mtrIP" class="col-form-label">{{ $t('mtrtest.Note2') }}</label>
</div>
<div class="col-12 col-md-auto mt-2 mt-md-0">
<div class="row justify-content-between">
<div class="col-auto">
<select id="mtrIP" class="form-select jn-ping-form-select" v-model="selectedIP"
:class="{ 'bg-dark text-light': isDarkMode }">
<option disabled value="">{{ $t('mtrtest.SelectIP') }}</option>
<option v-for="ip in allIPs" :key="ip" :value="ip">{{ ip }}</option>
</select>
</div>
<div class="col-auto">
<button class="btn btn-primary" @click="startmtrCheck"
:disabled="mtrCheckStatus === 'running' || selectedIP === ''">
<span
v-if="mtrCheckStatus === 'idle' || mtrCheckStatus === 'finished' || mtrCheckStatus === 'error'">{{
$t('mtrtest.Run') }}</span>
<span v-if="mtrCheckStatus === 'running'" class="spinner-grow spinner-grow-sm"
aria-hidden="true"></span>
</button>
</div>
</div>
</div>
</div>

<!-- Result Display -->
<div id="mtrresult" class="m-3" v-if="mtrResults.length > 0">
<ul class="nav nav-underline" role="tablist">
<li class="nav-item" v-for="(result, index) in mtrResults" :key="result.country">
<a class="nav-link px-2 fw-medium" :class="[{ active: index === 0 }, isDarkMode ? 'text-light' : 'text-secondary']" data-bs-toggle="tab" :href="'#tabContent' + index"
role="tab">
{{ result.country }} <span :class="'fi fi-' + result.country.toLowerCase()"></span>
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade" :class="{ show: index === 0, active: index === 0 }"
v-for="(result, index) in mtrResults" :key="'content' + result.country" :id="'tabContent' + index"
role="tabpanel">
<div class="card card-body border-0 mt-3" :class="[isDarkMode ? 'bg-secondary text-light' : 'bg-light']">
<pre>{{ result.rawOutput }}</pre>
</div>
</div>
</div>
</div>

<div id="mtrresult-error" v-if="mtrCheckStatus === 'error'">
<p class="text-center text-danger">{{ $t('mtrtest.Error') }}</p>
</div>

</div>
</div>
</div>
</div>
</div>
</template>

<script>
import { ref, computed, watch } from 'vue';
import { useStore } from 'vuex';
export default {
name: 'MTRtest',
// 引入 Store
setup() {
const store = useStore();
const isDarkMode = computed(() => store.state.isDarkMode);
const isMobile = computed(() => store.state.isMobile);
const ipDataCards = computed(() => store.state.Global_ipDataCards);
const allIPs = ref([]); // 创建响应式引用
const getAllIPs = (cards) => {
let Global_allIPs = []; // 初始化数组
cards.forEach(card => {
if (card.ip && !card.ip.includes(' ') && !card.ip.includes(':')) {
Global_allIPs.push(card.ip);
}
});
Global_allIPs = [...new Set(Global_allIPs)]; // 去重
allIPs.value = Global_allIPs; // 更新 allIPs 响应式引用
};
// 监听 ipDataCards 的变化
watch(ipDataCards, (newVal) => {
getAllIPs(newVal);
});
return {
isDarkMode,
isMobile,
allIPs,
};
},
data() {
return {
selectedIP: '',
mtrResults: {},
mtrCheckStatus: "idle",
}
},
methods: {
// 发起 mtr 测试
startmtrCheck() {
// 清空上一次结果
this.mtrResults = [];
let tryCount = 0;
// 子函数:发起 mtr 请求
const sendmtrRequest = async () => {
this.mtrCheckStatus = "running";
try {
const response = await fetch("https://api.globalping.io/v1/measurements", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
limit: 16,
locations: [
{ country: "HK" },
{ country: "TW" },
{ country: "CN" },
{ country: "JP" },
{ country: "SG" },
{ country: "IN" },
{ country: "RU" },
{ country: "US" },
{ country: "CA" },
{ country: "AU" },
{ country: "GB" },
{ country: "DE" },
{ country: "FR" },
{ country: "BR" },
{ country: "ZA" },
{ country: "SA" },
],
target: this.selectedIP, // 使用用户选中的 IP 地址
type: "mtr",
measurementOptions: {
"port": 80,
"protocol": "ICMP"
}
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Error sending mtr request:", error);
}
};
// 子函数:获取 mtr 结果
const fetchmtrResults = async (id) => {
try {
const response = await fetch(`https://api.globalping.io/v1/measurements/${id}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
this.processmtrResults(data);
if (data.status === "in-progress" && tryCount < 4) {
setTimeout(() => fetchmtrResults(id), 1000);
tryCount++;
} else {
// 如果 this.mtrResults 是空数组,返回错误信息
if (this.mtrResults.length === 0) {
this.mtrCheckStatus = "error";
} else {
this.mtrCheckStatus = "finished";
}
}
} catch (error) {
console.error("Error fetching mtr results:", error);
}
};
// 执行流程
sendmtrRequest().then(data => {
if (data && data.id) {
setTimeout(() => {
fetchmtrResults(data.id);
}, 1000);
}
});
},
processmtrResults(data) {
const cleanedData = data.results
.filter(item => item.result.status === "finished")
.filter(item => item.result.rawOutput !== null)
.map(item => ({
country: item.probe.country,
rawOutput: item.result.rawOutput,
}));
this.mtrResults = cleanedData;
},
},
}
</script>

<style scoped></style>
1 change: 1 addition & 0 deletions src/components/nav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
}}</a>
<a class="nav-link" :class="{ 'text-white jn-deactive': isDarkMode }" href="#PingTest"> {{ $t('nav.PingTest')
}}</a>
<a class="nav-link" :class="{ 'text-white jn-deactive': isDarkMode }" href="#MTRTest"> {{ $t('nav.MTRTest') }}</a>
</div>
</div>
</nav>
Expand Down
2 changes: 1 addition & 1 deletion src/components/speedtest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<p>{{ $t('speedtest.Note') }}</p>
</div>
<div class="row">
<div class="col-12">
<div class="col-12 mb-3">
<div class="card jn-card" :class="{ 'dark-mode dark-mode-border': isDarkMode }">
<div class="card-body">
<div class="progress" style="height: 20px; margin: 4pt 0 20pt 0;"
Expand Down
13 changes: 12 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"WebRTC": "WebRTC Test",
"DNSLeakTest": "DNS Leak Test",
"SpeedTest": "Speed Test",
"PingTest": "Global Latency"
"PingTest": "Global Latency",
"MTRTest": "MTR Test"
},
"ipInfos": {
"id": "ipinfos",
Expand Down Expand Up @@ -88,6 +89,16 @@
"Run": "Run Test",
"Error": "Test failed, it looks like your IP is not allowed to perform Ping test."
},
"mtrtest": {
"id": "mtrtest",
"Title": "MTR Test",
"Note": "MTR test will be performed on servers located in different continents and regions around the world to measure the connection path of your IP. MTR test results will be very useful during network diagnostics.",
"Note2": "Currently only supports IPv4 addresses, please select your IP address for testing",
"SelectIP": "Select an IP Address",
"Region": "Region",
"Run": "Run Test",
"Error": "Test failed, it looks like your IP is not allowed to perform MTR test."
},
"ipcheck": {
"id": "ipcheck",
"Title": "IP Check",
Expand Down
13 changes: 12 additions & 1 deletion src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"WebRTC": "WebRTC 测试",
"DNSLeakTest": "DNS 泄漏测试",
"SpeedTest": "网速测试",
"PingTest": "全球测速"
"PingTest": "全球测速",
"MTRTest": "MTR 测试"
},
"ipInfos": {
"id": "ipinfos",
Expand Down Expand Up @@ -88,6 +89,16 @@
"Run": "运行测试",
"Error": "测试失败,看起来你的 IP 不允许进行 Ping 测试。"
},
"mtrtest": {
"id": "mtrtest",
"Title": "MTR 测试",
"Note": "将从分布在全球不同大洲和地区的服务器,分别对你的 IP 进行 MTR 测试,并获取连接路径。在进行网络检测的时候,MTR 测试结果将非常有用。",
"Note2": "目前仅支持 IPv4 地址,请选取你的 IP 地址进行测试",
"SelectIP": "选择一个 IP 地址",
"Region": "地区",
"Run": "运行测试",
"Error": "测试失败,看起来你的 IP 不允许进行 MTR 测试。"
},
"ipcheck": {
"id": "ipcheck",
"Title": "IP 查询",
Expand Down

0 comments on commit 549146e

Please sign in to comment.