using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Infrastructure.Extensions; using Infrastructure.Models; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Renci.SshNet; namespace APService { public class ApService { private readonly IHostingEnvironment _env; private readonly IConfiguration _configuration; private readonly IHttpClientFactory _httpClientFactory; private CancellationTokenSource _tokenSource; private static readonly object thisLock = new object(); public ApService(IHostingEnvironment env, IConfiguration configuration, IHttpClientFactory httpClientFactory) { this._env = env; this._configuration = configuration; this._httpClientFactory = httpClientFactory; } public void Start() { this._tokenSource = new CancellationTokenSource(); Task.Run(async () => { while (!_tokenSource.IsCancellationRequested) { Update(this.GetModel()); await Task.Delay(this._configuration.GetValue("timer.seconds") * 1000); } }); } public void Update(NotifyModel model) { try { var url = $"http://{this._configuration["node.url"]}/Notify"; Console.WriteLine(url); var hc = this._httpClientFactory.CreateClient(); var task = this._httpClientFactory.CreateClient().PostAsync(url, new FormUrlEncodedContent(model.ToList())); task.Wait(); using (var response = task.Result) { using (var content = response.Content) { var value = content.ReadAsStringAsync().Result; Console.WriteLine($"end:{url}:{value}"); } } } catch (Exception ex) { ex.PrintStack(); } } public NotifyModel GetModel() { var host = string.IsNullOrEmpty(this._configuration["server.ip"]) ? "localhost" : this._configuration["server.ip"]; var prot = Convert.ToInt32(Regex.Match(this._configuration["server.urls"], @"(?<=:)\d+").Value); var sysinfo = this.RunCommand("sysinfo"); var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var model = new NotifyModel { CategoryName = "AP", CategoryNumber = "01", Name = "AP", Number = Regex.Match(this.RunCommand("get boarddata"), @"Serial#:\s*(\d+)").Groups[1].Value, Icon = "ap", IsOnline = true, BaseUrl = $"http://{host}:{prot}/ap", ApiPath = "/api" }; model.Data.Add(new DataModel { Key = "name", Type = DataValueType.Text.ToString(), Name = "名称", Value = "RuckusAP", DisplayOrder = 1 }); model.Data.Add(new DataModel { Key = "cpu", Type = DataValueType.Int.ToString(), Name = "CPU", Value = Regex.Match(sysinfo, @"CPU\s*:\s*([\d]+)\.[\d]+%").Groups[1].Value, Unit = "%", DisplayOrder = 2 }); var physicalMemory = double.Parse(Regex.Match(sysinfo, @"\s*(\d+)\s*KB\s*\(total\)").Groups[1].Value); var freePhysicalMemory = double.Parse(Regex.Match(sysinfo, @":\s*(\d+)\s*KB\s*\(free\)").Groups[1].Value); var memoryUsage = (physicalMemory - freePhysicalMemory) / physicalMemory * 100; model.Data.Add(new DataModel { Key = "memory", Type = DataValueType.Int.ToString(), Name = "内存", Value = memoryUsage.ToString("F0"), Unit = "%", Description = $"{((physicalMemory - freePhysicalMemory) / 1024 / 1024.0).ToString("F1")}/{(physicalMemory / 1024 / 1024.0).ToString("f1")} GB", DisplayOrder = 3 }); model.Data.Add(new DataModel { Key = "dhcps", Type = DataValueType.Int.ToString(), Name = "连接数", Value = (Regex.Matches(this.RunCommand("get dhcps"), @"[\d\.]{7,15}").Count() - 2).ToString(), DisplayOrder = 4 }); var (ip, netmask, gateway, dns) = this.GetNet(); model.Data.Add(new DataModel { Key = "ip", Type = DataValueType.Text.ToString(), Name = "IP", Value = ip, DisplayOrder = 5 }); model.Data.Add(new DataModel { Key = "netmask", Type = DataValueType.Text.ToString(), Name = "子网掩码", Value = netmask, DisplayOrder = 6 }); model.Data.Add(new DataModel { Key = "gateway", Type = DataValueType.Text.ToString(), Name = "网关", Value = gateway, DisplayOrder = 7 }); model.Data.Add(new DataModel { Key = "dns", Type = DataValueType.Text.ToString(), Name = "DNS", Value = dns, DisplayOrder = 8 }); return model; } public (string ip, string netmask, string gateway, string dns) GetNet() { var groups = Regex.Match(this.RunCommand("get ipaddr wan"), @"IP:\s+([\d\.]+)\s+Netmask\s+([\d\.]+)\s+Gateway\s+([\d\.]+)").Groups; var dns = Regex.Match(this.RunCommand("get dns"), @"DNS\s+1\s+:\s+([\d\.]+)").Groups[1].Value; return (groups[1].Value, groups[2].Value, groups[3].Value, dns); } public string RunCommand(string command) { var result = string.Empty; try { lock (thisLock) { var ip = this._configuration["ap.ip"]; var port = this._configuration.GetValue("ap.port"); var usr = this._configuration["ap.usr"]; var pwd = this._configuration["ap.pwd"]; using (var client = new SshClient(ip, port, usr, pwd)) { client.Connect(); using (var stream = client.CreateShellStream("AP", 80, 24, 800, 600, 1024)) { using (var reader = new StreamReader(stream)) { using (var writer = new StreamWriter(stream)) { writer.AutoFlush = true; this.Sleep(); reader.ReadToEnd(); //usr writer.WriteLine(usr); this.Sleep(); reader.ReadToEnd(); //pwd writer.WriteLine(pwd); this.Sleep(); reader.ReadToEnd(); //cmd writer.WriteLine(command); var isEnd = false; int i = 0; while (!isEnd && i < 100) { this.Sleep(); string line = null; while ((line = reader.ReadLine()?.Trim()) != null) { if (line == "OK") { isEnd = true; break; } if (!string.IsNullOrEmpty(line)) { //Console.WriteLine($"^{line}$"); result += $"{line}\r\n"; } } i += 1; } } } } } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); result = ex.Message; } return result; } private void Sleep() { Thread.Sleep(300); } } }