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 参数属性
///
/// 服务区编码
///
private string SocketServerpartCode { get; set; }
///
/// 门店编码
///
private string SocketShopCode { get; set; }
///
/// 收银机号
///
private string SocketMachineCode { get; set; }
///
/// 文件传输服务接口地址
///
private string DataServerApiUrl { get; set; }
///
/// Socket客户端实例
///
private WebSocket4Net.WebSocket PosWebSocketClient { get; set; }
///
/// Sokct客户端通讯线程
///
private Thread ClientStateThread { get; set; }
///
/// 客户端通讯线程运行状态
///
public bool ClientRuning { get; set; }
///
/// Socket客户端运行状态
///
public int SocketState { get => (int)this.PosWebSocketClient.State; }
#endregion
#region 异步通知委托事件
///
/// 消息通知事件
///
public event Notify NotifyEvent;
///
/// 消息通知委托事件
///
///
///
public delegate void Notify(object sender, NotifyEventArgs e);
#endregion
#region 构造函数 -> Socket客户端
///
/// Socket客户端
///
/// Socket服务端通讯地址
/// 服务区编码
/// 门店编码
/// 收银机号
/// 文件传输服务接口地址
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客户端服务连接成功事件
///
/// 连接成功监听事件
///
///
///
private void PosWebSocketClient_Opened(object sender, EventArgs e)
{
//执行通知
NotifyEvent?.Invoke(this, new NotifyEventArgs()
{
NotifyLoggerType = CommonDictionary.LoggerType.公共通知,
NotifyLoggerTime = DateTime.Now,
NotifyLoggerMessage = $"Socket客户端创建连接。"
});
}
#endregion
#region 事件 -> Socket客户端服务错误监听事件
///
/// Socket错误监听事件
///
///
///
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客户端接收消息处理事件
///
/// Socket客户端接收消息处理事件
///
///
///
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(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通讯启动方法
///
/// Socket通讯启动方法
///
///
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心跳握手检查
///
/// Socket心跳连接
///
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消息触发传输和结果上报
///
/// Soket消息启动数据获取
///
/// Socket连接会话
/// 传输的数据类型(指定需要获取的数据)
/// 操作时间(回传服务端发送过来的消息时间值)
/// 服务器消息唯一标识号
/// 指令执行参数
/// 上传PB数据压缩文件指令参数格式:服务区编码|门店编码|收银机号|账期开始时间|账期结束时间
/// 示例:888888|042002|2238|20210812164608|20210824103647
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 方法 -> 第三步和第四步:收银数据压缩文件检测和上传
///
/// 收银数据压缩文件检测和上传
///
///
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(
"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 方法 -> 文件传输进度处理事件
///
/// 文件传输进度处理事件
///
///
///
private void Uploader_OnUploading(object sender, UploadEventArgs e)
{
}
#endregion
#region 方法 -> 创建服务区本地服务器系统日志文件压缩包并将其上传
///
/// 创建服务区本地服务器系统日志文件压缩包并将其上传
///
/// 日志文件日期
///
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(
"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
}
}