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.

820 lines
29 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
{
//20240203 subin 注释掉
//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;
}
}
}
}