前言
在前端有时候需要输入ip,为了提高用户体验我们增加个Ping的检测工具,但是注意这里的Ping实际上是代理Ping,即服务端代理客户端是Ping,因此Ping的结果是基于服务端的网络拓扑来的。
效果


前端实现
这里直接写成了组件,
组件使用
<ping-tool ref="ping" :ip="xxx.ip"/>
组件源码
<template>
<div class="ping">
<div v-if="'WAIT' === status">
<el-link @click='startPing' type="primary">Ping 检测</el-link>
</div>
<div v-if="'PING' === status">正在Ping IP:{{this.ip}}<i class="el-icon-loading"/></div>
<div v-if="'ERROR' === status">IP:{{this.ip}}格式错误
<el-button @click='startPing' size='mini' type="primary" icon="el-icon-refresh" circle/>
</div>
<div v-if="'FINISHED' === status">
<div v-if="pingResult.pingSuccess === true" style="color:mediumseagreen">
Ping IP:{{this.pingResult.pingIp}} 成功({{this.pingResult.delay}}ms)
<el-button @click='startPing' size='mini' type="primary" icon="el-icon-refresh" circle/>
</div>
<div v-else style="color:red">
Ping IP:{{this.pingResult.pingIp}} 失败
<el-button @click='startPing' size='mini' type="primary" icon="el-icon-refresh" circle/>
</div>
</div>
<el-tooltip class="item" effect="dark" content="Ping的结果仅供参考,因为Ping实际上是服务器完成的,具体还是要依据此ip实际的使用环境评估"
placement="left">
<i style='margin-left: 5px' class="el-icon-warning"/>
</el-tooltip>
</div>
</template>
<script>
import {CommApi} from "../api/api/commApi";
export default {
name: "PingTool",
data() {
return {
status: 'WAIT',
pingResult: {
pingIp: '',
pingSuccess: false
}
}
},
props: {
ip: {
type: String,
default: ''
}
},
methods: {
async startPing() {
if (!this.ip || this.ip.length === 0 || !(/^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/).test(this.ip)) {
this.status = 'ERROR'
return
}
if(this.status === 'PING'){
return
}
this.status = 'PING'
let rep = await CommApi.pingIpCheck(this.ip)
let data = rep.data
this.status = 'FINISHED'
this.pingResult = data
}
}
}
</script>
<style scoped>
.ping {
margin: 5px;
display: flex;
align-items: center;
}
</style>
后端代码(JAVA)
利用
hutool的网络工具包,但是处理逻辑加强了下,取了ping延迟的平均值,以及重试机制
@GetMapping("/pingIpCheck")
@ResponseBody
public RestObjectResponse<PingIpResult> pingIpCheck(@RequestParam("ip") String ip) {
int timeoutCount = 0;
int allPingTime = 0;
boolean pingResult;
for (int i = 0; i < 5; i++) {
StopWatch time = StopWatch.createStarted();
boolean result = NetUtil.ping(ip, 2000);
allPingTime += time.getTime();
if (!result) {
timeoutCount++;
}
if (timeoutCount >= 3) {
break;
}
}
if (timeoutCount <= 1) {
pingResult = true;
} else {
pingResult = false;
}
PingIpResult result = new PingIpResult();
result.setPingIp(ip);
result.setPingSuccess(pingResult);
if (pingResult) {
result.setDelay(allPingTime / 5);
} else {
result.setDelay(-1);
}
return RestObjectResponse.ok(result);
}
@Getter
@Setter
public static class PingIpResult {
private boolean pingSuccess;
private String pingIp;
private int delay = -1;
}
本文介绍了如何在前端实现一个Ping检测工具,通过服务端代理客户端进行Ping操作,提供更好的用户体验。详细讲解了前端组件的使用和源码,以及后端JAVA代码的实现,包括计算平均延迟和重试机制。
171万+

被折叠的 条评论
为什么被折叠?



