883 lines
44 KiB
C#
883 lines
44 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Configuration;
|
||
using System.Data;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using BreakpointTransmission.Client;
|
||
using Transmission.SDK;
|
||
using Transmission.SDK.Model.Common;
|
||
using Transmission.SDK.Model.SocketTransfer;
|
||
|
||
namespace TransmissionClient
|
||
{
|
||
public class SuperSocketClient
|
||
{
|
||
#region 参数属性
|
||
/// <summary>
|
||
/// 服务区编码
|
||
/// </summary>
|
||
private string SocketServerpartCode { get; set; }
|
||
/// <summary>
|
||
/// 门店编码
|
||
/// </summary>
|
||
private string SocketShopCode { get; set; }
|
||
/// <summary>
|
||
/// 收银机号
|
||
/// </summary>
|
||
private string SocketMachineCode { get; set; }
|
||
/// <summary>
|
||
/// 文件传输服务接口地址
|
||
/// </summary>
|
||
private string DataServerApiUrl { get; set; }
|
||
/// <summary>
|
||
/// Socket客户端实例
|
||
/// </summary>
|
||
private WebSocket4Net.WebSocket PosWebSocketClient { get; set; }
|
||
/// <summary>
|
||
/// Sokct客户端通讯线程
|
||
/// </summary>
|
||
private Thread ClientStateThread { get; set; }
|
||
/// <summary>
|
||
/// 客户端通讯线程运行状态
|
||
/// </summary>
|
||
public bool ClientRuning { get; set; }
|
||
/// <summary>
|
||
/// Socket客户端运行状态
|
||
/// </summary>
|
||
public int SocketState { get => (int)this.PosWebSocketClient.State; }
|
||
#endregion
|
||
|
||
#region 异步通知委托事件
|
||
/// <summary>
|
||
/// 消息通知事件
|
||
/// </summary>
|
||
public event Notify NotifyEvent;
|
||
/// <summary>
|
||
/// 消息通知委托事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
public delegate void Notify(object sender, NotifyEventArgs e);
|
||
#endregion
|
||
|
||
#region 构造函数 -> Socket客户端
|
||
/// <summary>
|
||
/// Socket客户端
|
||
/// </summary>
|
||
/// <param name="socketServerURL">Socket服务端通讯地址</param>
|
||
/// <param name="serverpartCode">服务区编码</param>
|
||
/// <param name="shopCode">门店编码</param>
|
||
/// <param name="machineCode">收银机号</param>
|
||
/// <param name="dataServerApiUrl">文件传输服务接口地址 </param>
|
||
public SuperSocketClient(string socketServerURL, string serverpartCode,
|
||
string shopCode, string machineCode, string dataServerApiUrl)
|
||
{
|
||
this.PosWebSocketClient = new WebSocket4Net.WebSocket(socketServerURL);
|
||
this.PosWebSocketClient.Opened += PosWebSocketClient_Opened;
|
||
this.PosWebSocketClient.MessageReceived += PosWebSocketClient_MessageReceived;
|
||
this.PosWebSocketClient.Error += PosWebSocketClient_Error;
|
||
this.SocketServerpartCode = serverpartCode;
|
||
this.SocketShopCode = shopCode;
|
||
this.SocketMachineCode = machineCode;
|
||
this.DataServerApiUrl = dataServerApiUrl;
|
||
}
|
||
#endregion
|
||
|
||
#region 事件 -> Socket客户端服务连接成功事件
|
||
/// <summary>
|
||
/// 连接成功监听事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void PosWebSocketClient_Opened(object sender, EventArgs e)
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"Socket客户端创建连接。"
|
||
});
|
||
}
|
||
#endregion
|
||
|
||
#region 事件 -> Socket客户端服务错误监听事件
|
||
/// <summary>
|
||
/// Socket错误监听事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void PosWebSocketClient_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
|
||
{
|
||
////执行通知
|
||
//NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
//{
|
||
// NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
// NotifyLoggerTime = DateTime.Now,
|
||
// NotifyLoggerMessage = $"Socket客户端错误:{e.Exception.Message}"
|
||
//});
|
||
}
|
||
#endregion
|
||
|
||
#region 事件 -> Socket客户端接收消息处理事件
|
||
/// <summary>
|
||
/// Socket客户端接收消息处理事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void PosWebSocketClient_MessageReceived(object sender, WebSocket4Net.MessageReceivedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
WebSocket4Net.WebSocket webSocket = (WebSocket4Net.WebSocket)sender;
|
||
|
||
#region 接收服务器端发送过来的指令
|
||
//判断是否Socket服务心跳握手消息,这里只处理服务器端发送过来的非心跳信息
|
||
if (e.Message.ToLower() != "online")
|
||
{
|
||
#region 处理服务器发送过来的指令消息
|
||
//定义反馈给服务器的消息体
|
||
SocketMessageModel sendMessage = new SocketMessageModel()
|
||
{
|
||
ServerpartCode = SocketServerpartCode,
|
||
ShopCode = SocketShopCode,
|
||
MachineCode = SocketMachineCode,
|
||
};
|
||
//解析服务器发送过来的消息
|
||
SocketMessageModel socketMessage = Newtonsoft.Json.JsonConvert.DeserializeObject<SocketMessageModel>(e.Message);
|
||
if (socketMessage.Data != null)
|
||
{
|
||
//数据下载的反馈
|
||
sendMessage.ConnectValue = "feedbackMsg";
|
||
sendMessage.Data = new SocketMessageModel.MessageData()
|
||
{
|
||
SocketMsgGuid = socketMessage.Data.SocketMsgGuid,
|
||
TableName = socketMessage.Data.TableName,
|
||
OperateTime = socketMessage.Data.OperateTime
|
||
};
|
||
|
||
byte[] sendByte = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(sendMessage));
|
||
//发送应答信息给服务器
|
||
webSocket.Send(sendByte, 0, sendByte.Length);
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"云指令解析成功。"
|
||
});
|
||
if (socketMessage.ConnectValue == "offlineMsg")
|
||
{
|
||
#region 处理服务器发送过来的离线消息
|
||
//离线期间的数据可能存在多个,进行循环解析获取数据更新
|
||
string[] str_TableName = socketMessage.Data.TableName.Split(',');
|
||
for (int i = 0; i < str_TableName.Length; i++)
|
||
{
|
||
if (System.Enum.TryParse(str_TableName[i], out CommonDictionary.TableDataType tableDataType))
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"执行离线指令:{EnumHelper.GetEnumDesc(tableDataType)}," +
|
||
$"数据时间:{socketMessage.Data.OperateTime}"
|
||
});
|
||
//处理离线消息,对离线期间有更新的数据表进行数据获取更新
|
||
SocketDataTrans(webSocket, tableDataType, socketMessage.Data.OperateTime,
|
||
socketMessage.Data.SocketMsgGuid, socketMessage.Data.SocketContent);
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
else
|
||
{
|
||
#region 处理服务器发送过来的在线实时消息
|
||
if (System.Enum.TryParse(socketMessage.Data.TableName, out CommonDictionary.TableDataType tableDataType))
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"执行指令:{ EnumHelper.GetEnumDesc(tableDataType) }," +
|
||
$"数据时间:{socketMessage.Data.OperateTime}"
|
||
});
|
||
//处理在线消息,对有更新的数据表进行数据获取更新
|
||
SocketDataTrans(webSocket, tableDataType, socketMessage.Data.OperateTime,
|
||
socketMessage.Data.SocketMsgGuid, socketMessage.Data.SocketContent);
|
||
}
|
||
#endregion
|
||
}
|
||
}
|
||
else
|
||
{
|
||
#region 处理服务器发送过来的无效消息数据
|
||
//接收到错误的服务器消息时,反馈服务器告知信息错误,需要重新发送
|
||
sendMessage.ConnectValue = "errorData";
|
||
sendMessage.Data = new SocketMessageModel.MessageData()
|
||
{
|
||
TableName = "-1",
|
||
OperateTime = DateTime.Now
|
||
};
|
||
byte[] sendByte = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(sendMessage));
|
||
//发送应答信息给服务器
|
||
webSocket.Send(sendByte, 0, sendByte.Length);
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"反馈执行结果:解析失败,指令消息包[Data]内容无效。"
|
||
});
|
||
#endregion
|
||
}
|
||
#endregion
|
||
}
|
||
#endregion
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"服务区本地服务器指令执行失败,原因:{ex.Message}",
|
||
NotifyUploadState = true//将日志内容通过接口上传至云端
|
||
});
|
||
}
|
||
finally
|
||
{
|
||
if (e.Message.ToLower() != "online")
|
||
{
|
||
//记录文本日志
|
||
LogHelper.WriteLog("///------------执行结束------------///",
|
||
"", AppDomain.CurrentDomain.BaseDirectory + "/SocketLog");
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 方法 -> 第一步:建立消息通知服务连接,等待服务端发送消息
|
||
|
||
#region 方法 -> Socket通讯启动方法
|
||
/// <summary>
|
||
/// Socket通讯启动方法
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool Start()
|
||
{
|
||
bool result = true;
|
||
try
|
||
{
|
||
//打开Socket客户端连接
|
||
this.PosWebSocketClient.Open();
|
||
this.ClientRuning = true;
|
||
if (ClientStateThread == null || !ClientStateThread.IsAlive)
|
||
{
|
||
//心跳程序,每分钟与服务器握手一次
|
||
this.ClientStateThread = new Thread(new ThreadStart(CheckConnection))
|
||
{
|
||
IsBackground = true
|
||
};
|
||
this.ClientStateThread.Start();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"Socket服务启动连接失败。原因:{ex.Message}"
|
||
});
|
||
result = false;
|
||
}
|
||
return result;
|
||
}
|
||
#endregion
|
||
|
||
#region 方法 -> Socket心跳握手检查
|
||
/// <summary>
|
||
/// Socket心跳连接
|
||
/// </summary>
|
||
private void CheckConnection()
|
||
{
|
||
do
|
||
{
|
||
try
|
||
{
|
||
//检查当前服务连接状态,当Socket服务连接异常时,发起重新连接
|
||
if (this.PosWebSocketClient.State != WebSocket4Net.WebSocketState.Open &&
|
||
this.PosWebSocketClient.State != WebSocket4Net.WebSocketState.Connecting)
|
||
{
|
||
this.PosWebSocketClient.Close();
|
||
this.PosWebSocketClient.Open();
|
||
//暂停一秒等待服务连接
|
||
Thread.Sleep(1000);
|
||
}
|
||
if (this.PosWebSocketClient.State == WebSocket4Net.WebSocketState.Open)
|
||
{
|
||
//已连接成功的情况下,每分钟与服务器进行一次握手,确保服务不掉线
|
||
PosWebSocketClient.Send("state");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"Socket客户端重连异常:{ex.Message}"
|
||
});
|
||
}
|
||
//控制线程每分钟运行一次
|
||
Thread.Sleep(60 * 1000);
|
||
} while (this.ClientRuning);
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region 方法 -> 第二步和第四步:服务器端Soket消息触发传输和结果上报
|
||
/// <summary>
|
||
/// Soket消息启动数据获取
|
||
/// </summary>
|
||
/// <param name="webSocket">Socket连接会话</param>
|
||
/// <param name="tableDataType">传输的数据类型(指定需要获取的数据)</param>
|
||
/// <param name="operateTime">操作时间(回传服务端发送过来的消息时间值)</param>
|
||
/// <param name="socketMsgGuid">服务器消息唯一标识号</param>
|
||
/// <param name="socketContent">指令执行参数
|
||
/// <para>上传PB数据压缩文件指令参数格式:服务区编码|门店编码|收银机号|账期开始时间|账期结束时间</para>
|
||
/// <para>示例:888888|042002|2238|20210812164608|20210824103647</para></param>
|
||
private void SocketDataTrans(WebSocket4Net.WebSocket webSocket, CommonDictionary.TableDataType tableDataType,
|
||
DateTime operateTime, string socketMsgGuid, string socketContent)
|
||
{
|
||
//定义执行结果状态标识
|
||
bool ExcuteFlag;
|
||
//定义反馈给服务器的消息体
|
||
SocketMessageModel sendMessage = new SocketMessageModel()
|
||
{
|
||
ServerpartCode = SocketServerpartCode,
|
||
};
|
||
//定义socket通讯反馈的报文
|
||
byte[] sendByte;
|
||
|
||
switch (tableDataType)
|
||
{
|
||
case CommonDictionary.TableDataType.UploadSystemLog:
|
||
ExcuteFlag = CreateLogZipFile(operateTime);
|
||
|
||
#region 反馈指令执行结果给云端socket通讯服务
|
||
//反馈操作结果给服务器
|
||
sendMessage.ConnectValue = ExcuteFlag ? "Success" : "Fail";
|
||
sendMessage.Data = new SocketMessageModel.MessageData()
|
||
{
|
||
SocketMsgGuid = socketMsgGuid,
|
||
TableName = ((int)tableDataType).ToString(),
|
||
OperateTime = operateTime
|
||
};
|
||
sendByte = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(sendMessage));
|
||
//发送应答信息给服务器
|
||
webSocket.Send(sendByte, 0, sendByte.Length);
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"指令执行结果:{sendMessage.ConnectValue}"
|
||
});
|
||
#endregion
|
||
break;
|
||
default:
|
||
#region 调用本地接口,启动PB数据压缩文件生成和上传程序
|
||
DataTable dtEndaccount = new DataTable();
|
||
dtEndaccount.Columns.Add("SERVERPARTCODE", typeof(string));
|
||
dtEndaccount.Columns.Add("SHOPCODE", typeof(string));
|
||
dtEndaccount.Columns.Add("MACHINECODE", typeof(string));
|
||
dtEndaccount.Columns.Add("ENDACCOUNT_STARTDATE", typeof(string));
|
||
dtEndaccount.Columns.Add("ENDACCOUNT_DATE", typeof(string));
|
||
//接收到上传账期数据指令,调用区服本地接口启动PB数据压缩包生成工具
|
||
if (tableDataType == CommonDictionary.TableDataType.UploadEndaccount)
|
||
{
|
||
try
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(socketContent) && socketContent.Split('|').Length == 5)
|
||
{
|
||
DataRow drEndaccount = dtEndaccount.NewRow();
|
||
drEndaccount[0] = socketContent.Split('|')[0];
|
||
drEndaccount[1] = socketContent.Split('|')[1];
|
||
drEndaccount[2] = socketContent.Split('|')[2];
|
||
drEndaccount[3] = socketContent.Split('|')[3];
|
||
drEndaccount[4] = socketContent.Split('|')[4];
|
||
dtEndaccount.Rows.Add(drEndaccount);
|
||
}
|
||
else
|
||
{
|
||
#region 总部下发的传输指令,从区服数据库读取指定日期的账期记录
|
||
string _OracleConnStr = ConfigurationManager.AppSettings["OracleConnStr"].ToString();
|
||
OracleHelper oracleHelper = new OracleHelper(_OracleConnStr.Split(',')[0],
|
||
_OracleConnStr.Split(',')[4], _OracleConnStr.Split(',')[1],
|
||
_OracleConnStr.Split(',')[2], _OracleConnStr.Split(',')[3]);
|
||
|
||
string SQLString = string.Format(@"SELECT SERVERPARTCODE,SHOPCODE,MACHINECODE,
|
||
TO_CHAR(ENDACCOUNT_STARTDATE,'YYYYMMDDHH24MISS'),
|
||
TO_CHAR(ENDACCOUNT_DATE,'YYYYMMDDHH24MISS')
|
||
FROM HIGHWAY_EXCHANGE.T_ENDACCOUNT
|
||
WHERE FLAG = 1 AND SERVERPARTCODE = '{0}' AND ENDACCOUNT_DATE >= TO_DATE('{1}','YYYY/MM/DD') AND
|
||
ENDACCOUNT_DATE < TO_DATE('{1}','YYYY/MM/DD') + 1",
|
||
SocketServerpartCode, operateTime.ToShortDateString());
|
||
dtEndaccount = oracleHelper.ExcuteSqlGetDataSet(SQLString).Tables[0];
|
||
#endregion
|
||
}
|
||
|
||
if (dtEndaccount.Rows.Count > 0)
|
||
{
|
||
#region 逐条账期启动PB数据压缩文件生成程序,按照机器和账期维度逐个生成压缩文件
|
||
foreach (DataRow drEndaccount in dtEndaccount.Rows)
|
||
{
|
||
string LocalServiceUrl = "http://localhost:7080/DataTransferService/Service.asmx";
|
||
System.Collections.Hashtable hst_Hashtable = new System.Collections.Hashtable
|
||
{
|
||
{ "serverpartCode", drEndaccount[0] },
|
||
{ "shopCode", drEndaccount[1] },
|
||
{ "machineCode", drEndaccount[2] },
|
||
{ "startDate", drEndaccount[3] },
|
||
{ "endDate", drEndaccount[4] }
|
||
};
|
||
SoapWSHelper.QuerySoapWebServiceString(LocalServiceUrl, "PBDataZipUpload", hst_Hashtable);
|
||
//延迟3秒,等待接口启动程序
|
||
Thread.Sleep(3 * 1000);
|
||
}
|
||
#endregion
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"区服PB营收数据压缩文件上传指令处理结束,共生成{dtEndaccount.Rows.Count}个账期压缩文件。",
|
||
NotifyUploadState = true//将日志内容通过接口上传至云端
|
||
});
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"区服PB营收数据压缩文件上传指令发送失败,原因:{ex.Message}",
|
||
NotifyUploadState = true//将日志内容通过接口上传至云端
|
||
});
|
||
}
|
||
}
|
||
#endregion
|
||
break;
|
||
}
|
||
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"开始上传压缩文件"
|
||
});
|
||
|
||
#region 第二步:接收到服务端发送过来的传输指令后,延迟3秒,启动文件传输检测程序,文件传输失败或传输不完整延迟10秒,启动第二次文件传输检测
|
||
//接收到指令后等待3秒,再开始进行文件传输
|
||
Thread.Sleep(3000);
|
||
ExcuteFlag = UploadDataZipFile();//加上服务区、门店、机器号参数,只上传指定机器的文件
|
||
if (!ExcuteFlag)
|
||
{
|
||
//第一次压缩文件上传不成功,等待10秒,开始进行第二次文件传输
|
||
Thread.Sleep(10000);
|
||
ExcuteFlag = UploadDataZipFile();//加上服务区、门店、机器号参数,只上传指定机器的文件
|
||
}
|
||
#endregion
|
||
|
||
#region 第五步:执行完成后,上报传输文件总数、成功数量、失败数量、传输总耗时信息
|
||
//反馈操作结果给服务器
|
||
sendMessage.ConnectValue = ExcuteFlag ? "Success" : "Fail";
|
||
sendMessage.Data = new SocketMessageModel.MessageData()
|
||
{
|
||
SocketMsgGuid = socketMsgGuid,
|
||
TableName = ((int)tableDataType).ToString(),
|
||
OperateTime = operateTime
|
||
};
|
||
sendByte = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(sendMessage));
|
||
//发送应答信息给服务器
|
||
webSocket.Send(sendByte, 0, sendByte.Length);
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"指令执行结果:{sendMessage.ConnectValue}"
|
||
});
|
||
#endregion
|
||
}
|
||
#endregion
|
||
|
||
#region 方法 -> 第三步和第四步:收银数据压缩文件检测和上传
|
||
/// <summary>
|
||
/// 收银数据压缩文件检测和上传
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private bool UploadDataZipFile()
|
||
{
|
||
#region 第三步:本地压缩文件目录检测,获取压缩文件夹中未上传的文件清单
|
||
|
||
#region 获取区服本地压缩文件传输站点所在目录
|
||
//获取区服本地压缩文件传输站点所在目录
|
||
string str_BaseDirectory = IISWorkerHelper.GetPhysicPath("PosDataUpload");
|
||
if (string.IsNullOrWhiteSpace(str_BaseDirectory))
|
||
{
|
||
//区服不存在文件接收站点
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"执行失败,文件接收站点【PosDataUpload】不存在。",
|
||
NotifyUploadState = true //将日志内容通过接口上传至云端
|
||
});
|
||
return false;
|
||
}
|
||
#endregion
|
||
|
||
#region 拼接压缩文件保存的路径
|
||
//拼接压缩文件保存的路径
|
||
string str_ZipFileDir = Path.Combine(str_BaseDirectory, "Upload");
|
||
if (!Directory.Exists(str_ZipFileDir))
|
||
{
|
||
//压缩文件不存在,直接结束
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"无未上传的数据压缩文件。",
|
||
NotifyUploadState = true//将日志内容通过接口上传至云端
|
||
});
|
||
return true;
|
||
}
|
||
#endregion
|
||
|
||
#region 读取压缩文件存储目录下全部压缩文件
|
||
FileInfo[] file_DataFileList;
|
||
try
|
||
{
|
||
//读取压缩文件存储目录下全部压缩文件
|
||
file_DataFileList = new DirectoryInfo(str_ZipFileDir).GetFiles("*.zip", SearchOption.AllDirectories);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"获取未上传的压缩文件清单失败,原因:{ex.Message}",
|
||
NotifyUploadState = true//将日志内容通过接口上传至云端
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (file_DataFileList == null || file_DataFileList.Length == 0)
|
||
{
|
||
//没有需要上传的压缩文件,直接结束
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"无未上传的数据压缩文件。",
|
||
NotifyUploadState = true//将日志内容通过接口上传至云端
|
||
});
|
||
return true;
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region 第四步:逐个将未上传的文件传输到云服务器,记录传输用时。(上传成功的文件挪出监测文件夹)
|
||
|
||
#region 定义文件传输参数,初始化传输程序
|
||
int int_FileCount = file_DataFileList.Length;
|
||
int int_SuccessCount = 0;
|
||
//实例化文件传输程序
|
||
BreakpointUploader DataBreakpointUploader = new BreakpointUploader(1024 * 1024 * 1, UploadType.Append);
|
||
DataBreakpointUploader.OnUploading += Uploader_OnUploading;
|
||
#endregion
|
||
|
||
//在这里增加计时器,记录单个文件传输过程消耗的时间
|
||
System.Diagnostics.Stopwatch watchTotal = new System.Diagnostics.Stopwatch();
|
||
watchTotal.Start();
|
||
|
||
#region 逐个将未上传的文件传输到云服务器
|
||
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
|
||
foreach (FileInfo file_DataFile in file_DataFileList)
|
||
{
|
||
//判断压缩文件是否已上传,未上传的有效压缩文件才进行上传
|
||
if (file_DataFile.Length > 0)
|
||
{
|
||
string ServerpartShopCode = "";
|
||
if (file_DataFile.Name.Length > 16)
|
||
{
|
||
ServerpartShopCode = "服务区编码:" + file_DataFile.Name.Substring(0, 6) + ",门店编码:" +
|
||
file_DataFile.Name.Substring(6, 6) + "机器编码:" + (file_DataFile.Name.Substring(12, 1) == "0" ?
|
||
file_DataFile.Name.Substring(12, 3) : file_DataFile.Name.Substring(12, 4)) + ",文件名称:";
|
||
}
|
||
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"正在上传压缩包【{ ServerpartShopCode + file_DataFile.Name }】"
|
||
});
|
||
try
|
||
{
|
||
Internal.Header.M_Headers = new KeyValuePair<string, string>(
|
||
"x-app-name", System.Web.HttpUtility.UrlEncode("TransmissionClient"));
|
||
watch.Restart();
|
||
UploadStatus status = DataBreakpointUploader.Upload(file_DataFile.Directory.Name,file_DataFile.FullName, DataServerApiUrl);
|
||
watch.Stop();
|
||
if (status == UploadStatus.Completed)
|
||
{
|
||
int_SuccessCount += 1;
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"压缩包【{ ServerpartShopCode + file_DataFile.Name }】上传成功。" +
|
||
$"传输用时:{watch.Elapsed.TotalSeconds.ToString("F2")}秒"
|
||
});
|
||
|
||
#region 迁移已上传的文件到备份文件夹
|
||
try
|
||
{
|
||
//等待300毫秒,用于释放被传输占用的文件资源
|
||
Thread.Sleep(300);
|
||
//检查备份文件目录
|
||
if (!Directory.Exists(Path.Combine(str_BaseDirectory, "Zip", file_DataFile.Directory.Name)))
|
||
{
|
||
Directory.CreateDirectory(Path.Combine(str_BaseDirectory, "Zip", file_DataFile.Directory.Name));
|
||
}
|
||
//删除已经存在的备份文件
|
||
if (File.Exists(Path.Combine(str_BaseDirectory, "Zip", file_DataFile.Directory.Name, file_DataFile.Name)))
|
||
{
|
||
File.Delete(Path.Combine(str_BaseDirectory, "Zip", file_DataFile.Directory.Name, file_DataFile.Name));
|
||
//暂停300毫秒,等待资源释放
|
||
Thread.Sleep(300);
|
||
}
|
||
//移动已上传的文件到备份文件夹
|
||
File.Move(file_DataFile.FullName, Path.Combine(str_BaseDirectory,
|
||
"Zip", file_DataFile.Directory.Name, file_DataFile.Name));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"已上传的压缩包迁移失败,原因:{ex.Message}"
|
||
});
|
||
}
|
||
#endregion
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"压缩包上传失败,原因:{ex.Message}"
|
||
});
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
watchTotal.Stop();
|
||
#endregion
|
||
|
||
#region 第五步:执行完成后,上报传输文件总数、成功数量、失败数量、传输总耗时信息
|
||
if (int_FileCount > 0)
|
||
{
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"服务区编码:{ SocketServerpartCode }压缩包上传结束。" +
|
||
$"共{int_FileCount}个文件,上传成功{int_SuccessCount}个文件," +
|
||
$"上传失败{int_FileCount - int_SuccessCount}个文件。" +
|
||
$"传输总耗时:{watchTotal.Elapsed.TotalSeconds.ToString("F2")}秒",
|
||
NotifyUploadState = true//将日志内容通过接口上传至云端
|
||
});
|
||
}
|
||
#endregion
|
||
|
||
return int_FileCount > 0 && int_FileCount == int_SuccessCount;
|
||
}
|
||
#endregion
|
||
|
||
#region 方法 -> 文件传输进度处理事件
|
||
/// <summary>
|
||
/// 文件传输进度处理事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void Uploader_OnUploading(object sender, UploadEventArgs e)
|
||
{
|
||
}
|
||
#endregion
|
||
|
||
#region 方法 -> 创建服务区本地服务器系统日志文件压缩包并将其上传
|
||
/// <summary>
|
||
/// 创建服务区本地服务器系统日志文件压缩包并将其上传
|
||
/// </summary>
|
||
/// <param name="fileDate">日志文件日期</param>
|
||
/// <returns></returns>
|
||
public bool CreateLogZipFile(DateTime fileDate)
|
||
{
|
||
try
|
||
{
|
||
string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||
|
||
#region 第一步,创建日志文件临时文件夹
|
||
//日志文件临时保存目录
|
||
string str_DataSaveDir = Path.Combine(BaseDirectory, "LogFileTempDir",
|
||
SocketServerpartCode + "0000000000" + fileDate.ToString("yyyyMMdd"));
|
||
if (!Directory.Exists(str_DataSaveDir))
|
||
{
|
||
Directory.CreateDirectory(str_DataSaveDir);
|
||
}
|
||
#endregion
|
||
|
||
#region 第二步,读取通讯日志文件,并复制到临时文件夹中
|
||
//定义socket通讯日志文件目录
|
||
string SystemLogDirectory = Path.Combine(BaseDirectory, "SocketLog");
|
||
//读取日志文件信息
|
||
FileInfo[] file_DataFileList = new DirectoryInfo(SystemLogDirectory).GetFiles("*.log", SearchOption.AllDirectories);
|
||
for (int i = 0; i < file_DataFileList.Length; i++)
|
||
{
|
||
if (file_DataFileList[i].CreationTime.Date == fileDate.Date)
|
||
{
|
||
//复制指定日期的日志文件到临时目录
|
||
File.Copy(file_DataFileList[i].FullName, Path.Combine(str_DataSaveDir, file_DataFileList[i].Name));
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 第三步,创建本地日志文件压缩包保存目录
|
||
//定义日志文件压缩包保存目录
|
||
string str_DataZipDir = Path.Combine(BaseDirectory, "ZipFileDir", "SystemLog");
|
||
//建立日志文件压缩包保存目录
|
||
if (!Directory.Exists(str_DataZipDir))
|
||
{
|
||
Directory.CreateDirectory(str_DataZipDir);
|
||
}
|
||
#endregion
|
||
|
||
#region 第四步,从临时文件夹中读取日志文件,然后创建压缩包
|
||
//定义日志文件压缩包名称
|
||
string str_ZipFileName = SocketServerpartCode + "0000000000" + fileDate.ToString("yyyyMMdd") + "_SystemLog.zip";
|
||
//创建数据压缩文件
|
||
CL.IO.Zip.ZipHandler _ZipHandler = CL.IO.Zip.ZipHandler.GetInstance();
|
||
//执行文件压缩操作
|
||
_ZipHandler.PackDirectory(str_DataSaveDir, Path.Combine(str_DataZipDir, str_ZipFileName), (ProgressPercentage) => { });
|
||
//将执行结果显示在窗体中,并将日志上传至云端
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件生成,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"压缩包[{ fileDate.ToString("yyyy年MM月dd日") }]生成成功。",
|
||
NotifyUploadState = true //将日志内容通过接口上传至云端
|
||
});
|
||
#endregion
|
||
|
||
#region 第五步,删除日志文件临时保存目录
|
||
LogHelper.DeleteDirectory(str_DataSaveDir, false);
|
||
#endregion
|
||
|
||
//在这里增加计时器,记录单个文件传输过程消耗的时间
|
||
System.Diagnostics.Stopwatch watchTotal = new System.Diagnostics.Stopwatch();
|
||
watchTotal.Start();
|
||
|
||
#region 第六步,上传日志文件至云端
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"正在上传数据压缩文件:{ str_ZipFileName }"
|
||
});
|
||
try
|
||
{
|
||
//定义云端压缩包存储文件夹名称
|
||
Internal.Header.M_Headers = new KeyValuePair<string, string>(
|
||
"x-app-name", System.Web.HttpUtility.UrlEncode("TransmissionClient"));
|
||
|
||
//实例化文件传输程序
|
||
BreakpointUploader DataBreakpointUploader = new BreakpointUploader(1024 * 1024 * 1, UploadType.Append);
|
||
DataBreakpointUploader.OnUploading += Uploader_OnUploading;
|
||
//读取文件传输结果
|
||
UploadStatus status = DataBreakpointUploader.Upload(
|
||
"PosDataFile_SystemLog", Path.Combine(str_DataZipDir, str_ZipFileName), DataServerApiUrl);
|
||
|
||
if (status == UploadStatus.Completed)
|
||
{
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"压缩包上传成功。",
|
||
NotifyUploadState = true //将日志内容通过接口上传至云端
|
||
});
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"压缩包上传失败:{ex.Message}",
|
||
NotifyUploadState = true //将日志内容通过接口上传至云端
|
||
});
|
||
}
|
||
#endregion
|
||
|
||
watchTotal.Stop();
|
||
|
||
#region 第七步:执行完成后,上报传输总耗时信息
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件上传,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"压缩包上传结束。传输总耗时:{ watchTotal.Elapsed.TotalSeconds.ToString("F2") }秒",
|
||
NotifyUploadState = true //将日志内容通过接口上传至云端
|
||
});
|
||
#endregion
|
||
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//执行通知
|
||
NotifyEvent?.Invoke(this, new NotifyEventArgs()
|
||
{
|
||
NotifyLoggerType = CommonDictionary.LoggerType.压缩文件异常,
|
||
NotifyLoggerTime = DateTime.Now,
|
||
NotifyLoggerMessage = $"压缩包[{ fileDate.ToString("yyyy年MM月dd日") }]生成失败:{ex.Message}"
|
||
});
|
||
return false;
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
}
|