using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Transmission.SDK.ThreadPool;
using TransmissionClient.Model;
using BreakpointTransmission.Client;
using Newtonsoft.Json.Linq;
namespace TransmissionClient
{
///
/// MainWindow.xaml 的交互逻辑
/// 注:修改上传/下发的内容:在本页对应配置方法中修改
/// 修改上传/下发需要传输的表及传输类型、传输表时间间隔比例【分钟】、
/// 查询服务区本地数据表SQL语句、初始化传输时间字段、初始化表信息、
/// 定义表传输状态字段、单次最大传输数量:在ConfigThread.cs类中修改
/// 修改传输方法:在Transmission.SDK中ClientThread.cs类中修改
/// OpenTopThreads、OpenDownThreads、DownLoadDataByServerpaertCode、IsStartDownData方法
///
public partial class MainWindow : Window
{
#region Config参数
protected string _OracleConnStr = ConfigurationManager.AppSettings["OracleConnStr"].ToString();
protected string _TimerInterval = ConfigurationManager.AppSettings["Interval"].ToString();
#endregion
#region 参数定义
///
/// 运行状态上报线程
///
Thread StateUploadThread { get; set; }
///
/// 在线订单线程
///
Thread OnlineOrderThread { get; set; }
///
/// 在线订单线程
///
Thread OldSystemExceptionThread { get; set; }
///
/// 压缩文件上传线程
///
Thread FileUploadThread { get; set; }
///
/// 日结营收数据上传线程
///
ClientThread BusinessClientThread = new ClientThread();
///
/// 日结营收数据上传配置
///
ConfigThread BusinessConfigThread = null;
///
/// 日结营收数据上传线程(商业集团)
///
ClientThread BusinessClientThread_ZJ = new ClientThread();
///
/// 日结营收数据上传配置(商业集团)
///
ConfigThread BusinessConfigThread_ZJ = null;
///
/// 传输客户端定时器
///
DispatcherTimer CilentTimer = new DispatcherTimer();
///
/// 在线订单传输定时器
///
DispatcherTimer OnlineOrderTimer = new DispatcherTimer();
///
/// 公共数据库连接类
///
Transmission.SDK.OracleHelper LocalOracle;
///
/// 运行日志记录
///
DataTable TransResultTable;
///
/// 服务区信息缓存表
///
DataTable ServerPartTable;
///
/// 服务区信息缓存有效期
///
DateTime ServerPartCacheTime;
///
/// 多链路配置信息
///
List TransLinkConfigList { get; set; }
///
/// 多链路传输参数库配置
///
ConcurrentDictionary MulLinkConfigThreadList { get; set; }
///
/// 多链路传输线程库配置
///
ConcurrentDictionary MulLinkCilentThreadList { get; set; }
List TransferErrorNotify { get; set; }
bool IsReplaceColumn = false;
string ServerPartCode { get; set; }
#endregion
#region 文件传输Socket客户端
private SuperSocketClient SocketClient { get; set; }
private string SocketServerpartCode { get; set; }
#endregion
#region 方法 -> 主窗体事件
public MainWindow()
{
InitializeComponent();
}
///
/// 主窗体加载事件
///
///
///
private void Window_Loaded(object sender, RoutedEventArgs e)
{
#region 程序启动初始化
if (LocalOracle == null || !LocalOracle.ConnTest())
{
LocalOracle = new Transmission.SDK.OracleHelper(_OracleConnStr.Split(',')[0], _OracleConnStr.Split(',')[4],
_OracleConnStr.Split(',')[1], _OracleConnStr.Split(',')[2], _OracleConnStr.Split(',')[3]);
}
//绑定日结营收数据上传回调事件
BusinessClientThread.UploadStringEvent += new ClientThread.OutputResultsUploadArg(ClientThread_UploadStringEvent);
//绑定服务区基础数据下载回调事件
BusinessClientThread_ZJ.UploadStringEvent += new ClientThread.OutputResultsUploadArg(ClientThread_UploadStringEvent);
//初始化数据传输计时器
CilentTimer.Tick += CilentTimer_Tick;
double timeInterval = 0;
try
{
if (!double.TryParse(_TimerInterval, out timeInterval) || timeInterval < 1 || timeInterval > 10)
{
timeInterval = 5;
}
}
catch
{
timeInterval = 5;
}
timeInterval = timeInterval * 60 * 1000;
CilentTimer.Interval = TimeSpan.FromMilliseconds(timeInterval);
CilentTimer.Start();
//初始化在线订单传输定时器
OnlineOrderTimer.Tick += OnlineOrderTimer_Tick;
OnlineOrderTimer.Interval = TimeSpan.FromSeconds(3);
OnlineOrderTimer.Start();
BtnTimerState.Content = "停止";
Title = "服务区数据传输工具 TCv" + System.Windows.Forms.Application.ProductVersion;
int _FileCount = 0;
string[] _masks = { ".log" };
try
{
//清理过期日志文件
Transmission.SDK.LogHelper.DeleteFiles(
AppDomain.CurrentDomain.BaseDirectory + "\\log",
new string[] { ".log" }, false, false, ref _FileCount);
}
catch { }
#endregion
}
#endregion
#region 方法 -> 在线订单传输定时器事件
///
/// 在线订单传输定时器事件
///
///
///
private void OnlineOrderTimer_Tick(object sender, EventArgs e)
{
try
{
string _OnlineService;
try
{
_OnlineService = ConfigurationManager.AppSettings["OnlineService"];
}
catch
{
_OnlineService = "";
}
if (string.IsNullOrWhiteSpace(_OnlineService))
{
TransResultBeginInvoke(DateTime.Now, $"线上订单数据同步线程启动失败。原因:参数[OnlineService]未配置。");
OnlineOrderTimer.Stop();
return;
}
if (LocalOracle == null || !LocalOracle.ConnTest())
{
//初始化Oracle数据库连接字符串
LocalOracle = new Transmission.SDK.OracleHelper(_OracleConnStr.Split(',')[0], _OracleConnStr.Split(',')[4],
_OracleConnStr.Split(',')[1], _OracleConnStr.Split(',')[2], _OracleConnStr.Split(',')[3]);
}
//启动线上订单线程
if (OnlineOrderThread == null || !OnlineOrderThread.IsAlive)
{
OnlineOrderThread = new Thread(() => OnlineOrder(LocalOracle))
{
IsBackground = true
};
OnlineOrderThread.Start();
}
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, "在线订单传输启动失败:" + ex.Message);
Transmission.SDK.LogHelper.WriteServiceLog("在线订单传输启动失败:" + ex.Message);
}
}
#endregion
#region 事件 -> 主窗体按钮事件
///
/// 主窗体按钮事件
///
///
///
private void Button_Click(object sender, RoutedEventArgs e)
{
Button _Button = (Button)sender;
switch (_Button.Name)
{
case "BtnTimerState":
if (CilentTimer != null)
{
if (CilentTimer.IsEnabled)
{
CilentTimer.Stop();
_Button.Content = "启动";
TransResultBeginInvoke(DateTime.Now, "数据传输定时器已停止");
}
else
{
CilentTimer.Start();
_Button.Content = "停止";
TransResultBeginInvoke(DateTime.Now, "数据传输定时器已启动");
}
}
else
{
TransResultBeginInvoke(DateTime.Now, "数据传输定时器初始化失败,请重启程序!");
}
break;
case "BtnClosed":
if (CilentTimer != null && CilentTimer.IsEnabled)
{
CilentTimer.Stop();
}
Close();
break;
}
}
#endregion
#region 事件 -> 主线程定时器
///
/// 主线程定时器
///
///
///
private void CilentTimer_Tick(object sender, EventArgs e)
{
try
{
#region 初始化参数
//初始化数据库连接实例
if (LocalOracle == null || !LocalOracle.ConnTest())
{
LocalOracle = new Transmission.SDK.OracleHelper(_OracleConnStr.Split(',')[0], _OracleConnStr.Split(',')[4],
_OracleConnStr.Split(',')[1], _OracleConnStr.Split(',')[2], _OracleConnStr.Split(',')[3]);
}
#endregion
#region 检查服务区编码参数,未设置时,从数据库中获取
//检查服务区编码参数,未设置时,从数据库中获取
if (string.IsNullOrWhiteSpace(ServerPartCode))
{
try
{
//从数据库中读取服务区编码信息
var _ServerPartList =
from t in LocalOracle.ExcuteSqlGetDataSet(
"SELECT SERVERPARTCODE FROM HIGHWAY_EXCHANGE.T_SYSCODE").Tables[0].AsEnumerable()
group t by new
{
t1 = t.Field("SERVERPARTCODE")
} into m
select new
{
serverPartCode = m.Key.t1
};
//判断数据库中是否已读取到服务区信息
if (_ServerPartList.ToList().Count() > 0)
{
//多个服务区编码信息用英文逗号( , )拼接在一起,并保存到服务区信息参数属性中
ServerPartCode = string.Join(",", _ServerPartList.Select(p => p.serverPartCode));
}
}
catch { }
}
#endregion
#region 启动传输链路
TransResultBeginInvoke(DateTime.Now, "正在预启动上传子线程......");
//初始化门店日结营收数据上传线程配置
if (BusinessConfigThreadConfigure())
{
//启动门店日结营收数据上传线程
if (BusinessClientThread.onState(LocalOracle))
{
TransResultBeginInvoke(DateTime.Now, "日结营收上传线程预启动成功");
}
else
{
TransResultBeginInvoke(DateTime.Now, "日结营收上传线程预启动失败");
}
}
//初始化门店日结营收数据上传线程配置(商业集团)
if (BusinessConfigThreadConfigure_ZJ())
{
//启动门店日结营收数据上传线程
if (BusinessClientThread_ZJ.onState(LocalOracle))
{
TransResultBeginInvoke(DateTime.Now, "日结营收(商业集团)上传线程预启动成功");
}
else
{
TransResultBeginInvoke(DateTime.Now, "日结营收(商业集团)上传线程预启动失败");
}
}
#endregion
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, "传输启动失败:" + ex.Message);
Transmission.SDK.LogHelper.WriteServiceLog("传输启动失败:" + ex.Message);
}
}
#endregion
#region 事件 -> Socket客户端消息通知事件
///
/// Socket客户端消息通知事件
///
///
///
private void SocketClient_NotifyEvent(object sender, Transmission.SDK.Model.Common.NotifyEventArgs e)
{
string DirectoryName = AppDomain.CurrentDomain.BaseDirectory + "/SocketLog";
//记录文本日志
Transmission.SDK.LogHelper.WriteLog(e.NotifyLoggerMessage, "", DirectoryName);
#region 调用云端【/WebSocket/RecordLogToOracle】接口上报Socket消息通知执行结果到云端
try
{
Transmission.SDK.LogHelper.WriteServiceLog($"是否调用日志上传接口:" + e.NotifyUploadState);
//只有通知上传状态为True的消息才上传到云端
if (e.NotifyUploadState)
{
//文件上传耗时记录
string str_HttpURL = "http://pos.eshangtech.com:7198/webApi_publish/WebSocket/RecordLogToOracle";
string str_PostData = $"ServerpartCode={SocketServerpartCode}&ShopCode=000000&" +
$"MachineCode=0000&LogCentent={e.NotifyLoggerMessage}&TableName={(int)e.NotifyLoggerType}" +
$"&OperateTime={e.NotifyLoggerTime.ToString("yyyyMMddHHmmss")}";
string Result = Transmission.SDK.HttpDataHelper.OnPost($"{str_HttpURL}?{str_PostData}", str_PostData);
Transmission.SDK.LogHelper.WriteServiceLog($"开始上传日志【{str_PostData}】,上传结果:" + Result);
}
}
catch (Exception ex)
{
Transmission.SDK.LogHelper.WriteLog($"{ e.NotifyLoggerType }执行结果上报失败。原因:{ex.Message}", "", DirectoryName);
}
#endregion
//界面显示消息内容
TransResultBeginInvoke(e.NotifyLoggerTime, e.NotifyLoggerMessage);
}
#endregion
#region 事件 -> 大数据线程回传事件
private void BigData_ResultEvent(DateTime triggerTime, string resultMessage)
{
TransResultBeginInvoke(triggerTime, resultMessage);
}
#endregion
#region 方法 -> APP运行状态上报
///
/// APP运行状态上报
///
/// 数据库连接类
private void AppStateUpload(Transmission.SDK.OracleHelper localOracle)
{
try
{
if (ServerPartTable == null || ServerPartCacheTime < DateTime.Now)
{
//重置服务区信息缓存表
ServerPartTable = localOracle.ExcuteSqlGetDataSet(
@"SELECT SERVERPART_CODE,PROVINCE_CODE,SERVERPART_NAME
FROM HIGHWAY_EXCHANGE.T_SERVERPART").Tables[0];
if (ServerPartTable.Rows.Count == 0)
{
ServerPartCacheTime = DateTime.Now.AddMinutes(5);
}
else
{
ServerPartCacheTime = DateTime.Now.AddHours(1);
}
}
//定义APP运行状态上报传输地址
string _UploadRuningStateUrl = ConfigurationManager.AppSettings["UploadRuningStateUrl"];
if (string.IsNullOrWhiteSpace(_UploadRuningStateUrl))
{
TransResultBeginInvoke(DateTime.Now, $"APP运行状态上报失败。原因:参数[UploadRuningStateUrl]未配置。");
return;
}
foreach (DataRow ServerPartRow in ServerPartTable.Rows)
{
Hashtable hashtable = new Hashtable
{
//省份编码
{ "provinceCode", ServerPartRow["PROVINCE_CODE"].ToString() },
//省份名称
{ "provinceName", "" },
//服务区编码
{ "serverPartCode", ServerPartRow["SERVERPART_CODE"].ToString() },
//服务区名称
{ "serverPartName", ServerPartRow["SERVERPART_NAME"].ToString() },
//运行工具名称
{ "appName", System.Windows.Forms.Application.ProductName },
//运行工具版本号
{ "appVersion", $"TCv{System.Windows.Forms.Application.ProductVersion}" }
};
//上传运行工具状态信息
Transmission.SDK.SoapWSHelper.QuerySoapWebServiceString(
$"{_UploadRuningStateUrl}/Service.asmx", "UploadTransClientState", hashtable);
}
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, $"APP运行状态上报失败。原因:{ex.Message}");
}
}
#endregion
#region 方法 -> 线上订单传输
///
/// 线上订单传输
///
/// 数据库连接类
private void OnlineOrder(Transmission.SDK.OracleHelper localOracle)
{
TransResultBeginInvoke(DateTime.Now, $"正在启动线上订单数据同步线程......");
try
{
//定义线上订单数据同步地址
string _OnlineService;
try
{
_OnlineService = ConfigurationManager.AppSettings["OnlineService"];
}
catch
{
_OnlineService = "";
}
if (string.IsNullOrWhiteSpace(_OnlineService))
{
TransResultBeginInvoke(DateTime.Now, $"线上订单数据同步线程启动失败。原因:参数[OnlineService]未配置。");
return;
}
if (ServerPartTable == null || ServerPartCacheTime < DateTime.Now)
{
//重置服务区信息缓存表
ServerPartTable = localOracle.ExcuteSqlGetDataSet(
@"SELECT SERVERPART_CODE,PROVINCE_CODE,SERVERPART_NAME
FROM HIGHWAY_EXCHANGE.T_SERVERPART").Tables[0];
if (ServerPartTable.Rows.Count == 0)
{
ServerPartCacheTime = DateTime.Now.AddMinutes(5);
}
else
{
ServerPartCacheTime = DateTime.Now.AddHours(1);
}
}
OrderOnline.OnlineTransferResult transferResult;
foreach (DataRow ServerPartRow in ServerPartTable.Rows)
{
//分服务区下载已付款线上订单
TransResultBeginInvoke(DateTime.Now, $"正在下载[{ServerPartRow["SERVERPART_NAME"].ToString()}]线上订单数据......");
transferResult = OrderOnline.OrderBillDown(localOracle, _OnlineService,
ServerPartRow["SERVERPART_CODE"].ToString(), ServerPartRow["PROVINCE_CODE"].ToString());
TransResultBeginInvoke(DateTime.Now, $"[{ServerPartRow["SERVERPART_NAME"].ToString()}]线上订单下载完成;" +
$"\n本次订单获取总数:{transferResult.TotalCount}条;成功:{transferResult.SuccessCount}条;" +
$"失败:{transferResult.FailCount}条;过滤:{transferResult.FilterCount}条;耗时:{transferResult.TotalSeconds.ToString("F2")}秒。");
//分服务区上传已完成、已制作订单结果
TransResultBeginInvoke(DateTime.Now, $"正在上传[{ServerPartRow["SERVERPART_NAME"].ToString()}]线上订单接收结果数据......");
transferResult = OrderOnline.OrderBillUpload(localOracle, _OnlineService,
ServerPartRow["SERVERPART_CODE"].ToString(), ServerPartRow["PROVINCE_CODE"].ToString());
TransResultBeginInvoke(DateTime.Now, $"[{ServerPartRow["SERVERPART_NAME"].ToString()}]线上订单接收结果数据上传完成;" +
$"\n本次订单结果上传总数:{transferResult.TotalCount}条;成功:{transferResult.SuccessCount}条;" +
$"失败:{transferResult.FailCount}条;过滤:{transferResult.FilterCount}条;耗时:{transferResult.TotalSeconds.ToString("F2")}秒。");
}
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, $"线上订单数据同步线程启动失败。原因:{ex.Message}");
}
}
#endregion
#region 方法 -> 日结营收上传配置
///
/// 日结营收数据上传线程配置
///
private bool BusinessConfigThreadConfigure()
{
//初始化日结营收数据上传地址
string _SalesDataUrl;
try
{
_SalesDataUrl = ConfigurationManager.AppSettings["SalesDataUrl"];
}
catch
{
_SalesDataUrl = "";
}
if (string.IsNullOrWhiteSpace(_SalesDataUrl))
{
TransResultBeginInvoke(DateTime.Now, $"日结营收数据上传线程启动失败。原因:参数[SalesDataUrl]未配置。");
return false;
}
//初始化日结营收数据上传线程配置
if (BusinessConfigThread == null)
{
BusinessConfigThread = new ConfigThread("", IsReplaceColumn);
}
//定义上传表内容
BusinessClientThread.IsUpload(true, new List
{
"T_ENDACCOUNT_NEW", //日结账期表【新】
"T_ENDACCOUNT", //日结账期表【旧】
"T_PERSONSELL_NEW", //收银员交班表【新】
"T_PERSONSELL", //收银员交班表【旧】
});
BusinessClientThread.IsDownload(false);
try
{
//设置配置参数
BusinessClientThread.setConfiguration($"{_SalesDataUrl}/Service.asmx", "", ServerPartCode, "", "", "", "", 20, 1);
//配置线程参数
BusinessClientThread.setConfigThread(BusinessConfigThread);
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, "日结营收数据上传配置失败:" + ex.Message);
Transmission.SDK.LogHelper.WriteServiceLog("日结营收数据上传配置失败:" + ex.Message);
}
return true;
}
#endregion
#region 方法 -> 日结营收上传配置(商业集团)
///
/// 日结营收数据上传线程配置(商业集团)
///
private bool BusinessConfigThreadConfigure_ZJ()
{
//初始化日结营收数据上传地址
string _SalesDataUrl_ZJ;
try
{
_SalesDataUrl_ZJ = ConfigurationManager.AppSettings["SalesDataUrl_ZJ"];
}
catch
{
_SalesDataUrl_ZJ = "";
}
if (string.IsNullOrWhiteSpace(_SalesDataUrl_ZJ))
{
TransResultBeginInvoke(DateTime.Now, $"日结营收数据(商业集团)上传线程启动失败。原因:参数[SalesDataUrl_ZJ]未配置。");
return false;
}
//初始化日结营收数据上传线程配置
if (BusinessConfigThread_ZJ == null)
{
BusinessConfigThread_ZJ = new ConfigThread("", IsReplaceColumn);
}
//定义上传表内容
BusinessClientThread_ZJ.IsUpload(true, new List
{
"T_ENDACCOUNT_ZJ", //日结账期表
"T_PERSONSELL_ZJ", //收银员交班表
});
BusinessClientThread_ZJ.IsDownload(false);
try
{
//设置配置参数
BusinessClientThread_ZJ.setConfiguration($"{_SalesDataUrl_ZJ}/Service.asmx", "", ServerPartCode, "", "", "", "", 20, 1);
//配置线程参数
BusinessClientThread_ZJ.setConfigThread(BusinessConfigThread_ZJ);
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, "日结营收数据上传配置失败:" + ex.Message);
Transmission.SDK.LogHelper.WriteServiceLog("日结营收数据上传配置失败:" + ex.Message);
}
return true;
}
#endregion
#region 方法 -> 多链路传输配置
///
/// 多链路传输配置
///
///
private bool MulLinkConfigThreadConfigure()
{
//定义多链路传输配置获取服务地址
string str_MulLinkTransConfigUrl;
try
{
//默认读取Config文件中设置的传输链路配置地址;
str_MulLinkTransConfigUrl = ConfigurationManager.AppSettings["MulLinkTransConfigUrl"];
}
catch
{
str_MulLinkTransConfigUrl = "";
}
if (string.IsNullOrWhiteSpace(str_MulLinkTransConfigUrl))
{
//未配置多链路传输配置服务地址时,使用默认地址
str_MulLinkTransConfigUrl = "http://user.eshangtech.com:7088";
//TransResultBeginInvoke(DateTime.Now, $"多链路传输配置失败。原因:参数[MulLinkTransConfigUrl]未配置。");
//return false;
}
if (TransLinkConfigList == null)
{
//当启动程序时,调用服务获取多链路传输配置
TransLinkConfigList = OnTransLinkConfig(ServerPartCode, $"{str_MulLinkTransConfigUrl}/Service.asmx");
}
if (TransLinkConfigList == null || TransLinkConfigList.Count == 0)
{
//当云端未配置当前服务区多链路传输时,不继续初始化线程配置
TransResultBeginInvoke(DateTime.Now, $"多链路传输配置失败。原因:当前服务区云端未配置多链路传输。");
return false;
}
//遍历循环多链路配置列表,初始化每个链路的传输线程配置
foreach (var tlcm_TransLinkConfig in TransLinkConfigList)
{
//初始化链路传输数据类型,每个链路初始化一次
if (!MulLinkConfigThreadList.ContainsKey(tlcm_TransLinkConfig.TransLinkID))
{
MulLinkConfigThread mulLinkConfig = new MulLinkConfigThread(tlcm_TransLinkConfig.TableConfig, ServerPartCode);
MulLinkConfigThreadList.AddOrUpdate(tlcm_TransLinkConfig.TransLinkID, mulLinkConfig, (TransLinkID, MulLinkConfig) => mulLinkConfig);
}
//检查当前传输链路是否实例化传输线程配置
if (!MulLinkCilentThreadList.ContainsKey(tlcm_TransLinkConfig.TransLinkID))
{
//添加当前线程配置至线程列表
MulLinkCilentThread mulLinkCilent = new MulLinkCilentThread();
//绑定多链路线程上传回调事件
mulLinkCilent.UploadStringEvent += new MulLinkCilentThread.OutputResultsUploadArg(ClientThread_UploadStringEvent);
//绑定多链路线程下载回调事件
mulLinkCilent.DownloadStringEvent += new MulLinkCilentThread.OutputResultsDownArg(ClientThread_DownloadStringEvent);
MulLinkCilentThreadList.AddOrUpdate(tlcm_TransLinkConfig.TransLinkID, mulLinkCilent, (TransLinkID, MulLinkCilent) => mulLinkCilent);
}
//根据云端链路配置,设置需要启动传输的数据类型
List _TransTableList = new List();
foreach (var tc_TableConfig in tlcm_TransLinkConfig.TableConfig)
{
string[] str_TableName = tc_TableConfig.TableName.Split('.');
if (str_TableName.Length > 1)
{
_TransTableList.Add(str_TableName[1]);
//如多链路传输的数据上次给类型为状态反馈【T_STATEFEEDBACK】时需加上:区服数据版本上传表类型【T_SERVERPARTFEEDBACK】
if (str_TableName[1] == "T_STATEFEEDBACK")
{
_TransTableList.Add("T_SERVERPARTFEEDBACK");
}
}
else
{
_TransTableList.Add(str_TableName[0]);
//如多链路传输的数据上次给类型为状态反馈【T_STATEFEEDBACK】时需加上:区服数据版本上传表类型【T_SERVERPARTFEEDBACK】
if (str_TableName[0] == "T_STATEFEEDBACK")
{
_TransTableList.Add("T_SERVERPARTFEEDBACK");
}
}
}
try
{
//设置上传启动的表
MulLinkCilentThreadList[tlcm_TransLinkConfig.TransLinkID].IsUpload(true, _TransTableList);
//设置下发启动的表
MulLinkCilentThreadList[tlcm_TransLinkConfig.TransLinkID].IsDownload(true, _TransTableList);
//设置数据传输的链路地址
MulLinkCilentThreadList[tlcm_TransLinkConfig.TransLinkID].setConfiguration(tlcm_TransLinkConfig.TransLinkURL, "", ServerPartCode, "", "", "", "", 20, 1);
//设置数据传输线程参数
MulLinkCilentThreadList[tlcm_TransLinkConfig.TransLinkID].setConfigThread(MulLinkConfigThreadList[tlcm_TransLinkConfig.TransLinkID]);
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, $"链路[{tlcm_TransLinkConfig.TransLinkURL}]传输配置失败:" + ex.Message);
}
}
return true;
}
#endregion
#region 方法 -> 获取服务区多链路传输配置信息
///
/// 获取服务区多链路传输配置信息
///
/// 服务区编码,多个使用英文逗号【,】隔开,如:888888,888889
/// 多链路传输配置获取服务地址,格式:http://127.0.0.1:7080/service.asmx
///
private List OnTransLinkConfig(string serverpartCode, string serviceUrl)
{
List tlcm_TransLinkConfigList = new List();
try
{
//调用云端多链路配置服务接口,获取当前服务区多链路配置信息
string str_MulLinkTransConfig = Transmission.SDK.SoapWSHelper.QuerySoapWebServiceString(
serviceUrl, "GetMulLinkTransConfig", new Hashtable() { { "serverpartCodes", serverpartCode } });
if (string.IsNullOrWhiteSpace(str_MulLinkTransConfig))
{
//云端接口无返回值时,返回空白配置信息
return tlcm_TransLinkConfigList;
}
//反序列化返回值为JSon对象
JObject jObject_MulLinkTransConfig = JObject.Parse(str_MulLinkTransConfig);
if (jObject_MulLinkTransConfig.Property("IsSuccess") == null ||
jObject_MulLinkTransConfig.Property("IsSuccess").Value.ToString() != "1")
{
//当接口返回值:IsSuccess不等于1时,代表接口不成功,返回空白配置信息
return tlcm_TransLinkConfigList;
}
//解析多链路配置为List实体
List mlcm_MulLinkConfigModelList = jObject_MulLinkTransConfig.Property("Obj").Value.ToObject>();
//var tmp_MulLinkConfigList = mlcm_MulLinkConfigModelList.Select(p => new { p.MulLinkConfig_ID, p.InterfaceAddress, p.ServerPartCode }).Distinct().ToList();
//多链路传输地址去重
var tmp_MulLinkConfigList = mlcm_MulLinkConfigModelList.Select(p => new { p.MulLinkConfig_ID, p.InterfaceAddress }).Distinct().ToList();
//遍历循环获取到的多链路信息,转化为本地多链路配置实体属性
foreach (var _MulLinkConfig in tmp_MulLinkConfigList)
{
TransLinkConfigModel temp_TransLinkConfig = new TransLinkConfigModel();
//设置链路唯一标识,用于多链路线程配置识别
temp_TransLinkConfig.TransLinkID = (int)_MulLinkConfig.MulLinkConfig_ID;
//设置链路传输真实服务地址
temp_TransLinkConfig.TransLinkURL = $"{_MulLinkConfig.InterfaceAddress}/Service.asmx";
//temp_TransLinkConfig.ServerPartCode = _MulLinkConfig.ServerPartCode;
//设置链路传输服务区编码
temp_TransLinkConfig.ServerPartCode = serverpartCode;
//设置链路传输启动的表数据类型
temp_TransLinkConfig.TableConfig = new List();
List temp_TransTable = mlcm_MulLinkConfigModelList.FindAll(p =>
{
return p.MulLinkConfig_ID == _MulLinkConfig.MulLinkConfig_ID;//&& p.ServerPartCode == _MulLinkConfig.ServerPartCode;
});
//循环添加需要启动传输的数据表类型至配置列表
for (int i = 0; i < temp_TransTable.Count; i++)
{
TransTableConfigModel temp_TransTableConfig = new TransTableConfigModel();
if (temp_TransTable[i].TransFrequence != null)
{
temp_TransTableConfig.TransFrequence = (int)temp_TransTable[i].TransFrequence.Value;
}
temp_TransTableConfig.TableName = temp_TransTable[i].TableName;
temp_TransTableConfig.HistoryCallbackDate = temp_TransTable[i].HistoryCallBackDate;
temp_TransTableConfig.HistoryCallbackDays = (int)temp_TransTable[i].HistoryCallBackDays;
temp_TransTableConfig.StartTime = (int)temp_TransTable[i].StartTime;
temp_TransTableConfig.EndTime = (int)temp_TransTable[i].EndTime;
temp_TransLinkConfig.TableConfig.Add(temp_TransTableConfig);
}
tlcm_TransLinkConfigList.Add(temp_TransLinkConfig);
}
}
catch (Exception ex)
{
TransResultBeginInvoke(DateTime.Now, $"多链路传输配置获取异常。原因:{ex.Message}");
}
return tlcm_TransLinkConfigList;
}
#endregion
#region 事件 -> 上传回调事件
///
/// 上传回调事件
///
///
///
private void ClientThread_UploadStringEvent(UploadResultInfo uploadResultInfo, string resultString)
{
if (uploadResultInfo.StartToEnd)
{
TransResultBeginInvoke(DateTime.Now, resultString);
}
else
{
//于窗体中显示上传结果
TransResultBeginInvoke(DateTime.Now, string.Format("上传完成:[{0}]\n 总数:{1};成功:{2};过滤:{3};失败:{5};耗时:{4}{6}",
uploadResultInfo.TableName, uploadResultInfo.TotalNumber, uploadResultInfo.SuccessNumber,
uploadResultInfo.FilterNumber, uploadResultInfo.Elapsed.TotalSeconds.ToString("F2") + "秒",
uploadResultInfo.TotalNumber - uploadResultInfo.SuccessNumber - uploadResultInfo.FilterNumber,
(string.IsNullOrWhiteSpace(uploadResultInfo.InterfaceError) ? "" : (";\n 接口错误:" + uploadResultInfo.InterfaceError)) +
(string.IsNullOrWhiteSpace(uploadResultInfo.Error) ? "" : (";\n 本地错误:" + uploadResultInfo.Error))));
//若上传出现异常,则记录日志文本文件
if (!string.IsNullOrWhiteSpace(uploadResultInfo.InterfaceError) || !string.IsNullOrWhiteSpace(uploadResultInfo.Error))
{
//接口报错,记录异常变量,延迟重试传输
if (!string.IsNullOrWhiteSpace(uploadResultInfo.InterfaceError))
{
CheckTransferErrorNotify(uploadResultInfo.TableName, uploadResultInfo.ServiceURL);
}
//记录接口错误信息到文本日志中,供后续排查
if (!string.IsNullOrWhiteSpace(uploadResultInfo.InterfaceError))
{
Transmission.SDK.LogHelper.WriteServiceLog("接口错误:" + uploadResultInfo.InterfaceError +
$"\n{uploadResultInfo.TableDesc}数据上传错误:[{uploadResultInfo.TableName.Replace("HIGHWAY_EXCHANGE.", "")}];" +
$"耗时:{uploadResultInfo.Elapsed.TotalSeconds.ToString("F2") + "秒"}");
}
//记录本地错误信息到文本日志中,供后续排查
if (!string.IsNullOrWhiteSpace(uploadResultInfo.Error))
{
Transmission.SDK.LogHelper.WriteServiceLog("本地错误:" + uploadResultInfo.Error +
$"\n{uploadResultInfo.TableDesc}数据上传错误:[{uploadResultInfo.TableName.Replace("HIGHWAY_EXCHANGE.", "")}];" +
$"耗时:{uploadResultInfo.Elapsed.TotalSeconds.ToString("F2") + "秒"}");
}
}
else
{
if (TransferErrorNotify != null)
{
TransferErrorNotify.RemoveAll(p => p.ServiceURL == uploadResultInfo.ServiceURL);
}
}
}
}
#endregion
#region 事件 -> 下载回调事件
///
/// 下载回调事件
///
///
///
private void ClientThread_DownloadStringEvent(DownResultInfo downResultInfo, string resultString)
{
if (downResultInfo.StartToEnd)
{
TransResultBeginInvoke(DateTime.Now, resultString);
}
else
{
//于窗体中显示下载结果
TransResultBeginInvoke(DateTime.Now, string.Format("下载完成:[{0}]\n 总数:{1};新增:{2};更新:{3};过滤:{4};耗时:{5}{6}",
downResultInfo.TableName, downResultInfo.TotalNumber, downResultInfo.AddNumber, downResultInfo.UpNumber,
downResultInfo.FilterNumber, downResultInfo.Elapsed.TotalSeconds.ToString("F2") + "秒",
(string.IsNullOrWhiteSpace(downResultInfo.InterfaceError) ? "" : (";\n 接口错误:" + downResultInfo.InterfaceError)) +
(string.IsNullOrWhiteSpace(downResultInfo.Error) ? "" : (";\n 本地错误:" + downResultInfo.Error))));
//若下载出现异常,则记录日志文本文件
if (!string.IsNullOrWhiteSpace(downResultInfo.InterfaceError) || !string.IsNullOrWhiteSpace(downResultInfo.Error))
{
//接口报错,记录异常变量,延迟重试传输
if (!string.IsNullOrWhiteSpace(downResultInfo.InterfaceError))
{
CheckTransferErrorNotify(downResultInfo.TableName, downResultInfo.ServiceURL);
}
//记录接口错误信息到文本日志中,供后续排查
if (!string.IsNullOrWhiteSpace(downResultInfo.InterfaceError))
{
Transmission.SDK.LogHelper.WriteServiceLog("接口错误:" + downResultInfo.InterfaceError +
$"\n{downResultInfo.TableDesc}数据获取错误:[{downResultInfo.TableName.Replace("HIGHWAY_EXCHANGE.", "")}];耗时:{downResultInfo.Elapsed.TotalSeconds.ToString("F2") + "秒"}");
}
//记录本地错误信息到文本日志中,供后续排查
if (!string.IsNullOrWhiteSpace(downResultInfo.Error))
{
Transmission.SDK.LogHelper.WriteServiceLog("本地错误:" + downResultInfo.Error +
$"\n{downResultInfo.TableDesc}数据获取错误:[{downResultInfo.TableName.Replace("HIGHWAY_EXCHANGE.", "")}];耗时:{downResultInfo.Elapsed.TotalSeconds.ToString("F2") + "秒"}");
}
}
else
{
if (TransferErrorNotify != null)
{
TransferErrorNotify.RemoveAll(p => p.ServiceURL == downResultInfo.ServiceURL);
}
}
}
}
///
/// 接口异常记录缓存
///
/// 传输表名
/// 传输接口地址
private void CheckTransferErrorNotify(string tableName, string serviceURL)
{
//初始化缓存变量
if (TransferErrorNotify == null)
{
TransferErrorNotify = new List();
}
//读取缓存的对应数据表传输异常变量
TransferErrorNotifyModel tenm_TransferErrorNotify = TransferErrorNotify.Find(p => p.ServiceURL == serviceURL);
//
if (tenm_TransferErrorNotify == null)
{
tenm_TransferErrorNotify = new TransferErrorNotifyModel();
//tenm_TransferErrorNotify.TableName = tableName;
tenm_TransferErrorNotify.ServiceURL = serviceURL;
TransferErrorNotify.Add(tenm_TransferErrorNotify);
}
//记录接口报错重试次数
if (tenm_TransferErrorNotify.ErrorCount < 10)
{
tenm_TransferErrorNotify.ErrorCount += 1;
}
tenm_TransferErrorNotify.LastErrorTime = DateTime.Now;
if (tenm_TransferErrorNotify.ErrorCount >= 3)
{
tenm_TransferErrorNotify.RestartTime = DateTime.Now.AddMinutes(5);
}
}
#endregion
#region 委托 -> 运行日志委托处理事件
private delegate void DelegateTransResult(DateTime triggerTime, string resultMessage);
private void TransResultBeginInvoke(DateTime triggerTime, string resultMessage)
{
Dispatcher.BeginInvoke(new DelegateTransResult(TransResult), new object[] { triggerTime, resultMessage });
}
///
/// 运行日志呈现
///
/// 日志时间
/// 日志内容
private void TransResult(DateTime triggerTime, string resultMessage)
{
if (TransResultTable == null)
{
TransResultTable = ResultTable();
}
foreach (DataRow _RowTemp in TransResultTable.Select(string.Format("TransDate < '{0}'", DateTime.Now.AddHours(-1))))
{
TransResultTable.Rows.Remove(_RowTemp);
}
TransResultTable.AcceptChanges();
DataRow _DataRow = TransResultTable.NewRow();
_DataRow["TransDate"] = triggerTime;
_DataRow["TransResult"] = resultMessage;
TransResultTable.Rows.InsertAt(_DataRow, 0);
DataTransResult.AutoGenerateColumns = false;
DataTransResult.SelectionMode = DataGridSelectionMode.Single;
DataTransResult.ItemsSource = TransResultTable.DefaultView;
}
///
/// 运行日志记录表结构
///
///
private DataTable ResultTable()
{
DataTable _DataTable = new DataTable();
_DataTable.Columns.Add("TransDate", typeof(DateTime));
_DataTable.Columns.Add("TransResult", typeof(string));
return _DataTable;
}
#endregion
#region 方法 -> 比较两集合值是否需要更新
///
/// 方法 -> 比较两集合值
///
/// 集合
/// 集合
/// 是否区分大小写
private bool IsListCompare(List listOne, List listTwo, bool isCase = false)
{
if (listOne == null && listTwo == null)
{
return true;
}
if (listOne != null && listTwo != null)
{
if (listOne.Count == listTwo.Count)
{
foreach (string tempOne in listOne)
{
foreach (string tempTwo in listTwo)
{
if (isCase)
{
if (!tempOne.Equals(tempTwo))
{
return false;
}
}
else
{
if (!tempOne.ToUpper().Equals(tempTwo.ToUpper()))
{
return false;
}
}
}
}
return true;
}
}
return false;
}
#endregion
}
}