using System; using System.Collections.Generic; using System.IO; using Google.Protobuf.WellKnownTypes; using Sog; using System.Linq; using System.Reflection; using FileTransDataObject; namespace SMCenter { class CenterFileTransMng : Singleton { public CmdInfo transCmd; public bool isFinish; public FileTransMgr transMgr; public string errorMsg; private long lastTickTime; public CenterFileTransMng() { transMgr = new FileTransMgr(SMCenterUtils.HostName); transMgr._SendTransFileNotify = SendTransFileNotify; isFinish = true; } public void Clear() { TraceLog.Debug("CenterFileTransMng.Clear"); transCmd = null; errorMsg = null; isFinish = true; transMgr.Clear(); } public void Tick(long nowMs) { if (nowMs < lastTickTime + 1000) { return; } lastTickTime = nowMs; transMgr.Tick(nowMs); if (!isFinish && transMgr.IsFinish()) { isFinish = true; } } public int DoTransCmd(CmdInfo cmd) { if (transCmd != null) { errorMsg = string.Format("last trans not finish, cmd {0} file num {1}", transCmd.CMD, transMgr.TotalFile); TraceLog.Error("CenterFileTransMng.DoTransCmd {0}", errorMsg); return -1; } if (cmd.m_procs.Count == 0 && cmd.CMD != "pushagent" && cmd.CMD != "push") { errorMsg = "invalid trans agent num 0"; TraceLog.Error("CenterFileTransMng.DoTransCmd {0}", errorMsg); return -1; } transCmd = cmd; if (BeginTrans() != 0) { TraceLog.Error("CenterFileTransMng.DoTransCmd {0}", errorMsg); transCmd = null; return -1; } // 测试模式, 每次1字节, 模拟大文件 if (SMCenterUtils.Config.testMode == 1) { transMgr.SetContentSlice(1); } return 0; } // 初始化文件列表 private List GetTransFiles() { List fileList = new List(); if (transCmd.CMD == "pushcfg") { CmdUtils.GetPushCfgFile(transCmd, fileList, true); } else if (transCmd.CMD == "pushbin") { CmdUtils.GetPushBinFile(transCmd, fileList, true); } else if (transCmd.CMD == "pushsh") { CmdUtils.GetPushShellFile(transCmd, fileList, true); } else if (transCmd.CMD == "pushagent") { CmdUtils.GetPushAgentFile(transCmd, fileList, true); } else if (transCmd.CMD == "push") { CmdUtils.GetPushFile(transCmd, fileList, true); } return fileList; } // 初始化host列表 private List GetTransHosts() { List hostList = new List(); if (transCmd.CMD == "pushagent") { hostList.AddRange(SMCenterNet.Instance.GetAllAgent().Select(c => c.HostName)); } else { foreach (var name in transCmd.m_procs.Values.Select(p => p.SMApp.HostName).Distinct()) { if (SMCenterNet.Instance.GetClientInfoByName(name) != null) { hostList.Add(name); } } } return hostList; } private int BeginTrans() { var fileList = GetTransFiles(); if (fileList.Count == 0) { errorMsg = "trans file is 0"; return -1; } var hostList = GetTransHosts(); if (hostList.Count == 0) { errorMsg = "trans host is 0"; return -1; } if (transMgr.BeginTrans(fileList, hostList) != 0) { errorMsg = "begin trans fail, invalid files or hosts"; return -1; } isFinish = false; return 0; } public void SendTransFileNotify(long transSeq, List fileList, List hostList) { var notify = new SMTransFileNotify{TransSeq = transSeq, HostName = SMCenterUtils.HostName}; foreach (FileData file in fileList) { var attr = new FileAttr { FileMd5 = file.fileMd5, FileName = file.fileName, FileSize = file.FileSize, FilePath = file.writeFilePath, FileTime = file.fileWriteTime.ToFileTimeUtc() }; notify.FileList.Add(attr); } foreach (string name in hostList) { var client = SMCenterNet.Instance.GetClientInfoByName(name); client.SendMsg(notify, SMMsgID.TransFileNotify); } } public static int count = 0; public void OnFileContentReq(ClientInfo client, SMFileContentReq req) { // 测试模式, 50%丢包率 if (SMCenterUtils.Config.testMode == 1 && count++ % 2 == 1) { return; } var res = transMgr.OnFileContentReq(req); SMCenterNet.Instance.SendMsg(client, SMMsgID.FileContentRes, res); } public void OnFileRecvStateReq(ClientInfo client, SMFileRecvStateReq req) { transMgr.OnFileRecvStateReq(req); var res = new SMFileRecvStateRes {TransSeq = req.TransSeq, HostName = SMCenterUtils.HostName}; SMCenterNet.Instance.SendMsg(client, SMMsgID.FileRecvStateRes, res); } public void CancelPush() { if (transMgr.IsFinish()) { return; } TraceLog.Trace("CenterFileTransMng.CancelPush cmd {0}", transCmd.CMD); // 取消请求由agent根据实际情况处理 var notify = new SMCancelTransNotify { TransSeq = transMgr.transSeq, HostName = SMCenterUtils.HostName}; foreach (FileTransNode transNode in transMgr.transHosts.Values) { var client = SMCenterNet.Instance.GetClientInfoByName(transNode.receiverHost); if (client != null) { SMCenterNet.Instance.SendMsg(client, SMMsgID.CancelTransNotify, notify); } } } } }