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 } }