You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

819 lines
29 KiB
C#

9 months ago
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<ApiType, HttpClient> _clients = new Dictionary<ApiType, HttpClient>();
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<string, string> 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<IDictionary<string, string>, 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<string, string> parameters, HttpCallback responseBack)
//{
// Stopwatch watch = Stopwatch.StartNew();
// try
// {
// var httpClient = GetHttpClient(api);
// logger.Info("HttpClient建立连接:{0}ms", watch.ElapsedMilliseconds);
// var stringParams = new Func<IDictionary<string, string>, 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<string, string> 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<string>();
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("<pos.monitor>方法调用耗时<{0}>毫秒", watch.ElapsedMilliseconds);
}
}
catch (Exception ex)
{
logger.Error(ex, "POS监控异常");
}
}
/// <summary>
/// 获取指定驱动器的空间总大小(单位为M)
/// </summary>
/// <param name="diskName"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 获取指定驱动器的剩余空间总大小(单位为M)
/// </summary>
/// <param name="diskName"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 获取空闲内存(单位为M)
/// </summary>
/// <returns></returns>
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);
}
/// <summary>
/// 获取系统内存大小(单位M)
/// </summary>
/// <returns>内存大小</returns>
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;
}
/// <summary>
/// 指示开放平台是否可用
/// </summary>
/// <returns></returns>
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<string, string> 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("<common.sayhello>方法调用耗时<{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;
}
}
}
}