mirror of https://github.com/2dust/v2rayN
2dust
2 days ago
7 changed files with 0 additions and 232 deletions
@ -1,20 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
<PropertyGroup> |
||||
<TargetFramework>net8.0</TargetFramework> |
||||
<Nullable>enable</Nullable> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<Protobuf Include="Statistics.proto" /> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<PackageReference Include="Google.Protobuf" Version="3.28.3" /> |
||||
<PackageReference Include="Grpc.Net.Client" Version="2.66.0" /> |
||||
<PackageReference Include="Grpc.Tools" Version="2.67.0"> |
||||
<PrivateAssets>all</PrivateAssets> |
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||
</PackageReference> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -1,53 +0,0 @@
|
||||
syntax = "proto3"; |
||||
|
||||
package v2ray.core.app.stats.command; |
||||
option csharp_namespace = "ProtosLib.Statistics"; |
||||
|
||||
message GetStatsRequest { |
||||
// Name of the stat counter. |
||||
string name = 1; |
||||
// Whether or not to reset the counter to fetching its value. |
||||
bool reset = 2; |
||||
} |
||||
|
||||
message Stat { |
||||
string name = 1; |
||||
int64 value = 2; |
||||
} |
||||
|
||||
message GetStatsResponse { |
||||
Stat stat = 1; |
||||
} |
||||
|
||||
message QueryStatsRequest { |
||||
string pattern = 1; |
||||
bool reset = 2; |
||||
} |
||||
|
||||
message QueryStatsResponse { |
||||
repeated Stat stat = 1; |
||||
} |
||||
|
||||
message SysStatsRequest { |
||||
} |
||||
|
||||
message SysStatsResponse { |
||||
uint32 NumGoroutine = 1; |
||||
uint32 NumGC = 2; |
||||
uint64 Alloc = 3; |
||||
uint64 TotalAlloc = 4; |
||||
uint64 Sys = 5; |
||||
uint64 Mallocs = 6; |
||||
uint64 Frees = 7; |
||||
uint64 LiveObjects = 8; |
||||
uint64 PauseTotalNs = 9; |
||||
uint32 Uptime = 10; |
||||
} |
||||
|
||||
service StatsService { |
||||
rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {} |
||||
rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {} |
||||
rpc GetSysStats(SysStatsRequest) returns (SysStatsResponse) {} |
||||
} |
||||
|
||||
message Config {} |
@ -1,13 +0,0 @@
|
||||
using ProtosLib.Statistics; |
||||
|
||||
namespace ProtosLib |
||||
{ |
||||
public class Tests |
||||
{ |
||||
private StatsService.StatsServiceClient client_; |
||||
|
||||
public Tests() |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -1,135 +0,0 @@
|
||||
using Grpc.Core; |
||||
using Grpc.Net.Client; |
||||
using ProtosLib.Statistics; |
||||
|
||||
namespace ServiceLib.Services.Statistics |
||||
{ |
||||
public class StatisticsV2rayService |
||||
{ |
||||
private Models.Config _config; |
||||
private GrpcChannel? _channel; |
||||
private StatsService.StatsServiceClient? _client; |
||||
private bool _exitFlag; |
||||
private Action<ServerSpeedItem>? _updateFunc; |
||||
|
||||
public StatisticsV2rayService(Models.Config config, Action<ServerSpeedItem> updateFunc) |
||||
{ |
||||
_config = config; |
||||
_updateFunc = updateFunc; |
||||
_exitFlag = false; |
||||
|
||||
GrpcInit(); |
||||
|
||||
Task.Run(Run); |
||||
} |
||||
|
||||
private void GrpcInit() |
||||
{ |
||||
if (_channel is null) |
||||
{ |
||||
try |
||||
{ |
||||
_channel = GrpcChannel.ForAddress($"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort}"); |
||||
_client = new StatsService.StatsServiceClient(_channel); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
Logging.SaveLog(ex.Message, ex); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void Close() |
||||
{ |
||||
_exitFlag = true; |
||||
} |
||||
|
||||
private async void Run() |
||||
{ |
||||
while (!_exitFlag) |
||||
{ |
||||
await Task.Delay(1000); |
||||
try |
||||
{ |
||||
if (!_config.IsRunningCore(ECoreType.Xray)) |
||||
{ |
||||
continue; |
||||
} |
||||
if (_channel?.State == ConnectivityState.Ready) |
||||
{ |
||||
QueryStatsResponse? res = null; |
||||
try |
||||
{ |
||||
if (_client != null) |
||||
res = await _client.QueryStatsAsync(new QueryStatsRequest() { Pattern = "", Reset = true }); |
||||
} |
||||
catch |
||||
{ |
||||
} |
||||
|
||||
if (res != null) |
||||
{ |
||||
ParseOutput(res.Stat, out ServerSpeedItem server); |
||||
_updateFunc?.Invoke(server); |
||||
} |
||||
} |
||||
if (_channel != null) |
||||
await _channel.ConnectAsync(); |
||||
} |
||||
catch |
||||
{ |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void ParseOutput(Google.Protobuf.Collections.RepeatedField<Stat> source, out ServerSpeedItem server) |
||||
{ |
||||
server = new(); |
||||
long aggregateProxyUp = 0; |
||||
long aggregateProxyDown = 0; |
||||
try |
||||
{ |
||||
foreach (Stat stat in source) |
||||
{ |
||||
string name = stat.Name; |
||||
long value = stat.Value / 1024; //KByte |
||||
string[] nStr = name.Split(">>>".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); |
||||
string type = ""; |
||||
|
||||
name = name.Trim(); |
||||
|
||||
name = nStr[1]; |
||||
type = nStr[3]; |
||||
|
||||
if (name.StartsWith(Global.ProxyTag)) |
||||
{ |
||||
if (type == "uplink") |
||||
{ |
||||
aggregateProxyUp += value; |
||||
} |
||||
else if (type == "downlink") |
||||
{ |
||||
aggregateProxyDown += value; |
||||
} |
||||
} |
||||
else if (name == Global.DirectTag) |
||||
{ |
||||
if (type == "uplink") |
||||
{ |
||||
server.DirectUp = value; |
||||
} |
||||
else if (type == "downlink") |
||||
{ |
||||
server.DirectDown = value; |
||||
} |
||||
} |
||||
} |
||||
server.ProxyUp = aggregateProxyUp; |
||||
server.ProxyDown = aggregateProxyDown; |
||||
} |
||||
catch |
||||
{ |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue