using System.Collections.Generic; using System.Linq; using FileTransDataObject; using Google.Protobuf.WellKnownTypes; using Sog; namespace SMCenter { class CenterFilePullMng : Singleton { public CmdInfo pullCmd; public FileRecvMgr recvMgr; public bool isFinish; private List pullHosts; private long lastTickTime; private long beginPullTime; public CenterFilePullMng() { recvMgr = new FileRecvMgr(); recvMgr._SendFileContentReq = SendFileContentReq; recvMgr._SendFileRecvStateReq = SendFileRecvStateReq; pullHosts = new List(); isFinish = true; } public int DoPullCmd(CmdInfo cmd, out string msg) { if (pullCmd != null) { msg = string.Format("last pull not finish, cmd {0} pull host num {1}" , pullCmd.CMD, recvMgr.recvHosts.Count); TraceLog.Error("CenterFilePullMng.DoPullCmd {0}", msg); return -1; } msg = ""; BeginPull(cmd); return 0; } private void BeginPull(CmdInfo cmd) { pullCmd = cmd; isFinish = false; beginPullTime = AppTime.ServerAppTime.GetTime(); pullHosts.Clear(); pullHosts.AddRange(pullCmd.m_procs.Values.Select(p => p.SMApp.HostName)); } public void Clear() { TraceLog.Debug("CenterFilePullMng.Clear"); pullCmd = null; isFinish = true; beginPullTime = 0; recvMgr.Clear(); pullHosts.Clear(); } public void CancelPull() { if (pullCmd == null) { return; } TraceLog.Trace("CenterFilePullMng.CancelPull cmd {0}", pullCmd.CMD); foreach (string host in pullHosts) { recvMgr.CancelTrans(host); } } public void Tick(long nowMs) { if (nowMs < lastTickTime + 1000) { return; } lastTickTime = nowMs; recvMgr.Tick(nowMs); if (! isFinish) { int finishNum = 0; foreach (string host in pullHosts) { var recvNode = recvMgr.GetRecvNode(host); if (recvNode == null) { // 10秒后还没收到任何TransNotify算失败 if (nowMs > beginPullTime + 10000) { finishNum++; } } else if (recvNode.IsFinish) { finishNum++; } } if (finishNum == pullHosts.Count) { isFinish = true; } } } public void OnTransFileNotify(SMTransFileNotify notify) { recvMgr.OnTransFileNotify(notify); } public void OnFileContentRes(SMFileContentRes res) { recvMgr.OnFileContentRes(res); } public void OnFileRecvStateRes(ClientInfo client, SMFileRecvStateRes res) { recvMgr.OnFileRecvStateRes(res); } private void SendFileContentReq(FileRecvNode recvNode, FileRecvData fileData) { var client = SMCenterNet.Instance.GetClientInfoByName(recvNode.senderHost); if (client == null) { TraceLog.Error("CenterFilePullMng.SendFileContentReq agent {0} not register", recvNode.senderHost); return; } var req = new SMFileContentReq { FileName = fileData.fileName, FileMd5 = fileData.fileMd5, HostName = SMCenterUtils.HostName, ContentOffset = fileData.ReqFileOffset, TransSeq = recvNode.transSeq }; client.SendMsg(req, SMMsgID.FileContentReq); } private void SendFileRecvStateReq(FileRecvNode recvNode) { var client = SMCenterNet.Instance.GetClientInfoByName(recvNode.senderHost); if (client == null) { TraceLog.Error("CenterFilePullMng.SendFileRecvStateReq agent {0} not register", recvNode.senderHost); return; } SMFileRecvStateReq req = new SMFileRecvStateReq(); req.TransSeq = recvNode.transSeq; req.HostName = SMCenterUtils.HostName; foreach (FileRecvData fileData in recvNode.fileList) { req.FileList.Add(new FileRecvState { FileName = fileData.fileName, FileMd5 = fileData.fileMd5, RecvState = fileData.recvState, }); } client.SendMsg(req, SMMsgID.FileRecvStateReq); } } }