using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Management; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Net.Security; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Windows.Forms; using Newtonsoft.Json; using POSV.HttpApi; namespace POSV.Utils { //HttpClientHandler handler = new HttpClientHandler() //{ // Proxy = new WebProxy("http://127.0.0.1:8888") , // UseProxy = true , //}; //Console.WriteLine("GET: + " + TARGETURL); // // ... Use HttpClient. // HttpClient client = new HttpClient(handler); //var byteArray = Encoding.ASCII.GetBytes("username:password1234"); //client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); // HttpResponseMessage response = await client.GetAsync(TARGETURL); //HttpContent content = response.Content; //// ... Check Status Code //Console.WriteLine("Response StatusCode: " + (int)response.StatusCode); // // ... Read the string. // string result = await content.ReadAsStringAsync(); //// ... Display the result. public class HttpClientUtils { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private static object _lock = new object(); private static Dictionary _clients = new Dictionary(); private static int timeout = 30 * 1000; private static HttpClient GetHttpClient(OpenApi api) { HttpClient httpClient = null; var handler = new HttpClientHandler(); if (handler.SupportsAutomaticDecompression) { handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; } handler.Proxy = null; //handler.UseProxy = false; handler.UseDefaultCredentials = false; //HttpClientHandler handler = new HttpClientHandler() //{ // Proxy = new WebProxy("http://127.0.0.1:8888"), // UseProxy = true, //}; Interlocked.CompareExchange(ref httpClient, new HttpClient(handler) { BaseAddress = new Uri(api.Url) }, null); httpClient.DefaultRequestHeaders.Connection.Add("Keep-Alive"); httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"); //_httpClient.DefaultRequestHeaders.Add("Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8"); httpClient.DefaultRequestHeaders.Add("Accept", "*/*"); httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate"); //声明给服务器,客户端支持gzip解压 httpClient.DefaultRequestHeaders.Add("Accept-Language", "zh-cn,en-us;q=0.7,en;q=0.3"); httpClient.DefaultRequestHeaders.Add("Pragma", "no-cache"); httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache"); httpClient.DefaultRequestHeaders.Add("JW-API-VERSION", "1.0.0"); //zhangy 2019-11-24 10:13 httpClient.MaxResponseContentBufferSize = int.MaxValue; httpClient.DefaultRequestHeaders.ExpectContinue = false; httpClient.Timeout = TimeSpan.FromMilliseconds(timeout); return httpClient; } public static string PostAsync(OpenApi api, string url, SortedList parameters) { Stopwatch watch = Stopwatch.StartNew(); ServicePointManager.Expect100Continue = false; //提升系统外联的最大并发web访问数 ServicePointManager.DefaultConnectionLimit = 512; ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; try { logger.Info("请求参数:{0}", JsonUtils.Serialize(parameters)); var stringParams = new Func, string>((dic) => { string _result = ""; foreach (var param in dic) { if (_result.Length > 0) { _result += "&"; } _result += param.Key + "=" + HttpUtility.UrlEncode(param.Value); } return _result; }).Invoke(parameters); if (api.ApiType == ApiType.Card) { return CardPost(api, url, stringParams, watch); } if (api.ApiType == ApiType.WaiMai) { return WaiMaiPost(api, url, stringParams, watch); } if (parameters != null && parameters.ContainsKey("method")) { var methodName = parameters["method"]; switch (methodName.ToLower()) { //case "upload.business.order.plus": case "upload.business.log": case "common.sayhello": case "pos.monitor": case "program.product": //case "worker.login": { return Post(api, url, stringParams, watch); } } } //return Post(api, url, stringParams, watch); var httpClient = GetHttpClient(api); var content = new StringContent(stringParams, Encoding.UTF8, "application/x-www-form-urlencoded"); var task = httpClient.PostAsync(url, content); task.Result.EnsureSuccessStatusCode(); HttpResponseMessage response = task.Result; var result = response.Content.ReadAsStringAsync(); var responseDetails = result.Result; //logger.Info("Sucessfully sent HTTP request to api Invoices with repsonse" + responseDetails); return responseDetails; } catch (Exception ex) { string message = "调用PostAsync方法发生错误"; if (parameters != null && parameters.ContainsKey("method")) { message = "调用<" + parameters["method"] + ">发生错误"; } logger.Error(ex, message); throw new Exception(message); } finally { string methodName = "NoDefined"; if (parameters != null && parameters.ContainsKey("method")) { methodName = parameters["method"]; } logger.Info("调用<{0}>方法,耗时<{1}>毫秒", methodName, watch.ElapsedMilliseconds); } } //public delegate void HttpCallback(string str); //public static void PostAsyncEx(OpenApi api, string url, SortedList parameters, HttpCallback responseBack) //{ // Stopwatch watch = Stopwatch.StartNew(); // try // { // var httpClient = GetHttpClient(api); // logger.Info("HttpClient建立连接:{0}ms", watch.ElapsedMilliseconds); // var stringParams = new Func, string>((dic) => // { // string _result = ""; // foreach (var param in dic) // { // if (_result.Length > 0) { _result += "&"; } // _result += param.Key + "=" + HttpUtility.UrlEncode(param.Value); // } // return _result; // }).Invoke(parameters); // var content = new StringContent(stringParams, Encoding.UTF8, "application/x-www-form-urlencoded"); // logger.Info("请求参数内容:{0}", JsonUtils.Serialize(parameters)); // httpClient.PostAsync(url, content).ContinueWith(t => // { // HttpResponseMessage respMsg = t.Result; // //读取请求结果 // respMsg.Content.ReadAsStringAsync().ContinueWith(r => // { // var response = r.Result; // responseBack(response); // }); // }); // } // catch (Exception ex) // { // string message = "调用PostAsync方法发生错误"; // if (parameters != null && parameters.ContainsKey("name")) // { // message = "调用<" + parameters["name"] + ">发生错误"; // } // logger.Error(ex, message); // throw new Exception(message); // } // finally // { // string methodName = "NoDefined"; // if (parameters != null && parameters.ContainsKey("name")) // { // methodName = parameters["name"]; // } // logger.Info("调用<{0}>方法,耗时<{1}>毫秒", methodName, watch.ElapsedMilliseconds); // } //} public static string CardPost(OpenApi api, string url, string _data , Stopwatch watch) { logger.Info("网络请求分发至会员通道......."); try { System.GC.Collect(); // 创建httppost. HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //request.ServicePoint.Expect100Continue = false; //request.ServicePoint.UseNagleAlgorithm = false; //request.ServicePoint.ConnectionLimit = 65500; //request.AllowWriteStreamBuffering = false; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; //zhangy 2020-03-20 Add HttpWebRequest调用远程HTTPS速度慢 request.Referer = null; request.AllowAutoRedirect = true; request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; request.Accept = "*/*"; request.KeepAlive = false; request.Proxy = null; request.Timeout = timeout; request.ReadWriteTimeout = timeout; request.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5"); Encoding encoding = Encoding.UTF8; byte[] postBody = encoding.GetBytes(_data); using (Stream stream = request.GetRequestStream()) { stream.Write(postBody, 0, postBody.Length); } HttpWebResponse response = request.GetResponse() as HttpWebResponse; using (Stream stream = response.GetResponseStream()) { StreamReader reader = new StreamReader(stream, Encoding.UTF8); return reader.ReadToEnd(); } } catch (Exception ex) { string message = "调用Post方法发生错误"; logger.Error(ex, message); throw new Exception(message); } finally { logger.Info("CardPost执行耗时<{0}>毫秒", watch.ElapsedMilliseconds); } } public static string Post(OpenApi api, string url, string _data, Stopwatch watch) { logger.Info("网络请求分发到方法级通道......."); HttpWebRequest request = null; HttpWebResponse response = null; try { System.GC.Collect(); // 创建httppost. request = WebRequest.Create(url) as HttpWebRequest; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; //zhangy 2020-03-20 Add HttpWebRequest调用远程HTTPS速度慢 request.Referer = null; request.AllowAutoRedirect = true; request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; request.Accept = "*/*"; request.KeepAlive = false; request.Proxy = null; request.Timeout = timeout; request.ReadWriteTimeout = timeout; request.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5"); Encoding encoding = Encoding.UTF8; byte[] postBody = encoding.GetBytes(_data); using (Stream stream = request.GetRequestStream()) { stream.Write(postBody, 0, postBody.Length); } response = request.GetResponse() as HttpWebResponse; using (Stream stream = response.GetResponseStream()) { StreamReader reader = new StreamReader(stream, Encoding.UTF8); return reader.ReadToEnd(); } } catch (Exception ex) { string message = "调用Post方法发生错误"; logger.Error(ex, message); throw new Exception(message); } finally { if (response != null) { response.Close(); } if (request != null) { request.Abort(); } logger.Info("调用Post执行耗时<{0}>毫秒", watch.ElapsedMilliseconds); } } public static string WaiMaiPost(OpenApi api, string url, string _data, Stopwatch watch) { logger.Info("网络请求分发至外卖通道......."); try { // 创建httppost. HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; //zhangy 2020-03-20 Add HttpWebRequest调用远程HTTPS速度慢 request.Referer = null; request.AllowAutoRedirect = true; request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; request.Accept = "*/*"; request.KeepAlive = false; request.Proxy = null; request.Timeout = timeout; request.ReadWriteTimeout = timeout; request.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5"); Encoding encoding = Encoding.UTF8; byte[] postBody = encoding.GetBytes(_data); using (Stream stream = request.GetRequestStream()) { stream.Write(postBody, 0, postBody.Length); } HttpWebResponse response = request.GetResponse() as HttpWebResponse; using (Stream stream = response.GetResponseStream()) { StreamReader reader = new StreamReader(stream, Encoding.UTF8); return reader.ReadToEnd(); } } catch (Exception ex) { string message = "调用WaiMaiPost方法发生错误"; logger.Error(ex, message); throw new Exception(message); } finally { logger.Info("WaiMaiPost执行耗时<{0}>毫秒", watch.ElapsedMilliseconds); } } public static void PosMonitor() { try { if (Global.Instance.Online && Global.Instance.Authc != null) { Stopwatch watch = Stopwatch.StartNew(); OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business); SortedList parameters = OpenApiUtils.Instance.NewParameters(api); parameters.Add("method", "pos.monitor"); parameters.Add("storeId", Global.Instance.Authc.StoreId); parameters.Add("posNo", Global.Instance.Authc.PosNo); string osVersionName = GetOsVersion(Environment.OSVersion.Version); string servicePack = Environment.OSVersion.ServicePack; osVersionName = osVersionName + " " + servicePack; parameters.Add("os", osVersionName); bool is64Os = Environment.Is64BitOperatingSystem; parameters.Add("osType", is64Os ? "64" : "32"); parameters.Add("softwareVersion", Application.ProductVersion.ToString()); parameters.Add("memoryTotalSize", GetPhisicalMemory().ToString()); parameters.Add("memoryFreeSize", GetFreePhysicalMemory().ToString()); string baseDir = AppDomain.CurrentDomain.BaseDirectory; string diskName = baseDir.Substring(0, 1).ToUpper();//取首字母并转为大写 parameters.Add("diskName", diskName + ":"); parameters.Add("diskTotalSize", GetHardDiskSpace(diskName).ToString()); parameters.Add("diskFreeSize", GetHardDiskFreeSpace(diskName).ToString()); parameters.Add("cpuSize", Environment.ProcessorCount.ToString()); var storeName = Global.Instance.Worker.StoreInfo != null ? Global.Instance.Worker.StoreInfo.Name : Global.Instance.Authc.StoreName; parameters.Add("storeName", storeName);//门店名称 parameters.Add("aliasName", Global.Instance.Authc.PosNo);//pos别名 var ignoreParameters = new List(); ignoreParameters.Add("os"); ignoreParameters.Add("osType"); ignoreParameters.Add("softwareVersion"); ignoreParameters.Add("memoryTotalSize"); ignoreParameters.Add("memoryFreeSize"); ignoreParameters.Add("diskName"); ignoreParameters.Add("diskTotalSize"); ignoreParameters.Add("diskFreeSize"); ignoreParameters.Add("cpuSize"); ignoreParameters.Add("storeName"); ignoreParameters.Add("aliasName"); parameters.Add("sign", OpenApiUtils.Instance.Sign(api, parameters, ignoreParameters)); var response = PostAsync(api, api.Url, parameters); if (Constant.IsSuccessful(response)) { } else { } logger.Debug("方法调用耗时<{0}>毫秒", watch.ElapsedMilliseconds); } } catch (Exception ex) { logger.Error(ex, "POS监控异常"); } } /// /// 获取指定驱动器的空间总大小(单位为M) /// /// /// public static long GetHardDiskSpace(string diskName) { long totalSize = new long(); diskName = diskName + ":\\"; System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives(); foreach (System.IO.DriveInfo drive in drives) { if (drive.Name == diskName) { totalSize = drive.TotalSize / (1024 * 1024); } } return totalSize; } /// /// 获取指定驱动器的剩余空间总大小(单位为M) /// /// /// public static long GetHardDiskFreeSpace(string diskName) { long freeSpace = new long(); diskName = diskName + ":\\"; System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives(); foreach (System.IO.DriveInfo drive in drives) { if (drive.Name == diskName) { freeSpace = drive.TotalFreeSpace / (1024 * 1024); } } return freeSpace; } /// /// 获取空闲内存(单位为M) /// /// public static int GetFreePhysicalMemory() { long availablebytes = 0; try { ManagementClass mos = new ManagementClass("Win32_OperatingSystem"); foreach (ManagementObject mo in mos.GetInstances()) { if (mo["FreePhysicalMemory"] != null) { availablebytes = long.Parse(mo["FreePhysicalMemory"].ToString()); } } } catch { availablebytes = 0; } return (int)(availablebytes / 1024); } /// /// 获取系统内存大小(单位M) /// /// 内存大小 private static int GetPhisicalMemory() { ManagementObjectSearcher searcher = new ManagementObjectSearcher(); //用于查询一些如系统信息的管理对象 searcher.Query = new SelectQuery("Win32_PhysicalMemory ", "", new string[] { "Capacity" });//设置查询条件 ManagementObjectCollection collection = searcher.Get(); //获取内存容量 ManagementObjectCollection.ManagementObjectEnumerator em = collection.GetEnumerator(); long capacity = 0; while (em.MoveNext()) { ManagementBaseObject baseObj = em.Current; if (baseObj.Properties["Capacity"].Value != null) { try { capacity += long.Parse(baseObj.Properties["Capacity"].Value.ToString()); } catch { return 0; } } } return (int)(capacity / 1024 / 1024); } private static string GetOsVersion(Version ver) { string strClient = ""; if (ver.Major == 5 && ver.Minor == 0) { strClient = "Win2000"; } else if (ver.Major == 5 && ver.Minor == 1) { strClient = "WinXP"; } else if (ver.Major == 6 && ver.Minor == 0) { strClient = "WinVista"; } else if (ver.Major == 6 && ver.Minor == 1) { strClient = "Win7"; } else if (ver.Major == 6 && ver.Minor == 2) { strClient = "Win8+"; } else if (ver.Major == 10 && ver.Minor == 0) { strClient = "Win10"; } else { strClient = "未知"; } return strClient; } /// /// 指示开放平台是否可用 /// /// public static bool IsAvailable() { try { Stopwatch watch = Stopwatch.StartNew(); //是否有可用网卡 var networkLinkTask = NetworkUtils.IsNetworkLink(); //是否连接互联网 var connectedTask = NetworkUtils.IsConnectedToInternet(); //网络可用:a)网卡工作;b)可以联网 bool isConnected = networkLinkTask && connectedTask; //如果网络可用,检测开放平台 if (isConnected) { OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business); SortedList parameters = OpenApiUtils.Instance.NewParameters(api); parameters.Add("method", "common.sayhello"); parameters.Add("sign", OpenApiUtils.Instance.Sign(api, parameters)); var response = PostAsync(api, api.Url, parameters); if (Constant.IsSuccessful(response)) { isConnected = true; } else { isConnected = false; } logger.Debug("方法调用耗时<{0}>毫秒,结果<{1}>", watch.ElapsedMilliseconds, isConnected); } logger.Debug("网络检测耗时<{0}>毫秒,结果<{1}>", watch.ElapsedMilliseconds, isConnected); //这里发生过长时间无反应的情况 add by yangaming 20171230 try { var info = new SystemInfo(); if(info.CpuLoad > 0.85 || info.MemoryAvailable <= 100 * 1024 * 1024) { logger.Info("CPU占用率<{0}>,物理内存<{1}>,可用内存<{2}>", info.CpuLoad, info.PhysicalMemory, info.MemoryAvailable); } } catch (Exception ex) { logger.Error(ex, "获取CPU、内存使用情况发生异常"); } return isConnected; } catch (Exception ex) { logger.Error(ex, "无法连接开放平台"); return false; } } } public class SystemInfo { private int m_ProcessorCount = 0; //CPU个数 private PerformanceCounter pcCpuLoad; //CPU计数器 private long m_PhysicalMemory = 0; //物理内存 /// /// 构造函数,初始化计数器等 /// public SystemInfo() { //初始化CPU计数器 pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total"); pcCpuLoad.MachineName = "."; pcCpuLoad.NextValue(); //CPU个数 m_ProcessorCount = Environment.ProcessorCount; //获得物理内存 ManagementClass mc = new ManagementClass("Win32_ComputerSystem"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { if (mo["TotalPhysicalMemory"] != null) { m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString()); } } } public override string ToString() { return string.Format("{0}%-{1}M", (int)this.CpuLoad, this.MemoryAvailable / 1024 / 1024); } /// /// 获取CPU个数 /// public int ProcessorCount { get { return m_ProcessorCount; } } /// /// 获取CPU占用率 /// public float CpuLoad { get { return pcCpuLoad.NextValue(); } } /// /// 获取可用内存 /// public long MemoryAvailable { get { long availablebytes = 0; ManagementClass mos = new ManagementClass("Win32_OperatingSystem"); foreach (ManagementObject mo in mos.GetInstances()) { if (mo["FreePhysicalMemory"] != null) { availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString()); } } return availablebytes; } } /// /// 获取物理内存 /// public long PhysicalMemory { get { return m_PhysicalMemory; } } } }