Files
node_server/bot/info/instance/used_network.ts
T
2026-10-22 17:07:08 +08:00

63 lines
3.3 KiB
TypeScript

import {performance} from 'node:perf_hooks';
import type {Bot} from '@wp2508/mineflayer';
import {metadata, ResourceInfo} from '../resource_metrics.ts';
export interface NetworkInfo {
available: boolean;
received_bytes: number;
sent_bytes: number;
received_bytes_per_second: number | null;
sent_bytes_per_second: number | null;
interval_ms: number;
}
/** Totals include the first observed counters of every new socket. Unobserved old-socket tails are unknowable. */
export class NetworkCounter {
private socket: object | undefined;
private read = 0;
private written = 0;
private time: number | undefined;
private received = 0;
private sent = 0;
sample(socket: {bytesRead?: number; bytesWritten?: number} | undefined, now: number): NetworkInfo {
const read = socket?.bytesRead;
const written = socket?.bytesWritten;
const available = typeof read === 'number' && Number.isFinite(read) && read >= 0
&& typeof written === 'number' && Number.isFinite(written) && written >= 0;
const elapsed = this.time === undefined ? 0 : now - this.time;
const continuous = available && socket === this.socket && this.time !== undefined
&& read >= this.read && written >= this.written && elapsed > 0;
const dr = available ? (socket === this.socket && read >= this.read ? read - this.read : read) : 0;
const dw = available ? (socket === this.socket && written >= this.written ? written - this.written : written) : 0;
this.received += dr;
this.sent += dw;
if (available) {
this.socket = socket;
this.read = read;
this.written = written;
}
this.time = available ? now : undefined;
return {available, received_bytes: this.received, sent_bytes: this.sent,
received_bytes_per_second: continuous ? dr * 1000 / elapsed : null,
sent_bytes_per_second: continuous ? dw * 1000 / elapsed : null, interval_ms: continuous ? elapsed : 0};
}
}
export class init extends ResourceInfo<NetworkInfo> {
readonly name = 'used_network';
readonly i18n = metadata('机器人网络流量', '读取传输层套接字的字节计数,包含协议开销;'
+ '更换套接字后保留累计观察量,不包含旧套接字被替换前未观察到的尾部流量。', {
available: ['计数是否可用', '套接字是否同时提供有效的接收和发送字节计数'],
received_bytes: ['累计接收量', '累计观察到的接收流量,单位为字节'],
sent_bytes: ['累计发送量', '累计观察到的发送流量,单位为字节'],
received_bytes_per_second: ['接收速率', '接收流量速率,单位为字节每秒;缺少连续采样基线时为 null'],
sent_bytes_per_second: ['发送速率', '发送流量速率,单位为字节每秒;缺少连续采样基线时为 null'],
interval_ms: ['速率采样间隔', '通过单调时钟测得的实际速率采样间隔,单位为毫秒;缺少连续采样基线时为 0'],
});
constructor(bot: Bot) {
const counter = new NetworkCounter();
super(counter.sample(bot._client?.socket, performance.now()));
this.start(1000, () => { this.publish(counter.sample(bot._client?.socket, performance.now())); });
}
}