You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
338 lines
11 KiB
338 lines
11 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
using Sog;
|
|
using FileTransDataObject;
|
|
|
|
|
|
namespace SMAgent
|
|
{
|
|
class AgentFileTransMng : Singleton<AgentFileTransMng>
|
|
{
|
|
public SMAgentDoCommandReq pullReq;
|
|
|
|
public bool isFinish;
|
|
|
|
public string errorMsg;
|
|
|
|
private FileTransMgr transMgr;
|
|
|
|
private long lastTickTime;
|
|
|
|
private int testMode;
|
|
|
|
public AgentFileTransMng()
|
|
{
|
|
transMgr = new FileTransMgr(SMAgentUtils.HostName);
|
|
transMgr._SendTransFileNotify = SendTransFileNotify;
|
|
|
|
isFinish = true;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
TraceLog.Debug("AgentFileTransMng.Clear");
|
|
|
|
pullReq = 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;
|
|
Clear();
|
|
}
|
|
}
|
|
|
|
|
|
// pull文件时, SMAgentDoCommandRes直接回应Center, Center根据是不是在接收文件再确定是不是接收console的新命令
|
|
public int DoTransCmd(SMAgentDoCommandReq req)
|
|
{
|
|
if (pullReq != null)
|
|
{
|
|
errorMsg = string.Format("last file transfer not finish, cmd {0} file num {1}"
|
|
, pullReq.Command, transMgr.TotalFile);
|
|
TraceLog.Error("AgentFileTransMng.DoTransCmd {0}", errorMsg);
|
|
return -1;
|
|
}
|
|
|
|
pullReq = req;
|
|
|
|
if (BeginTrans() != 0)
|
|
{
|
|
TraceLog.Error("AgentFileTransMng.DoTransCmd {0}", errorMsg);
|
|
pullReq = null;
|
|
return -1;
|
|
}
|
|
|
|
testMode = req.TestMode;
|
|
// 测试模式, 每次传输1字节, 模拟大文件
|
|
if (testMode == 1)
|
|
{
|
|
transMgr.SetContentSlice(1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// 初始化文件列表
|
|
private List<FileData> GetTransFiles()
|
|
{
|
|
List<FileData> fileList = new List<FileData>();
|
|
|
|
if (pullReq.Command == "pullagentlog")
|
|
{
|
|
GetAgentLogFile(fileList);
|
|
}
|
|
else if (pullReq.Command == "pull")
|
|
{
|
|
GetPullFile(fileList);
|
|
}
|
|
|
|
return fileList;
|
|
}
|
|
|
|
|
|
public int BeginTrans()
|
|
{
|
|
var fileList = GetTransFiles();
|
|
if (fileList.Count == 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
var hostList = new List<string>();
|
|
hostList.Add(pullReq.CenterName);
|
|
|
|
if (transMgr.BeginTrans(fileList, hostList) != 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
isFinish = false;
|
|
return 0;
|
|
}
|
|
|
|
public void SendTransFileNotify(long transSeq, List<FileData> fileList, List<string> hostList)
|
|
{
|
|
var notify = new SMTransFileNotify {TransSeq = transSeq, HostName = SMAgentUtils.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)
|
|
{
|
|
SMAgentNet.Instance.SendMsgToCenter(notify, SMMsgID.TransFileNotify);
|
|
}
|
|
}
|
|
|
|
public static int count = 0;
|
|
public void OnFileContentReq(SMFileContentReq req)
|
|
{
|
|
// 测试模式, 模拟50%丢包率
|
|
if (testMode == 1 && count++ % 2 == 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var res = transMgr.OnFileContentReq(req);
|
|
SMAgentNet.Instance.SendMsgToCenter(res, SMMsgID.FileContentRes);
|
|
}
|
|
|
|
public void OnFileRecvStateReq(SMFileRecvStateReq req)
|
|
{
|
|
transMgr.OnFileRecvStateReq(req);
|
|
|
|
var res = new SMFileRecvStateRes {TransSeq = req.TransSeq, HostName = SMAgentUtils.HostName};
|
|
SMAgentNet.Instance.SendMsgToCenter(res, SMMsgID.FileRecvStateRes);
|
|
}
|
|
|
|
|
|
private int GetAgentLogFile(List<FileData> fileList)
|
|
{
|
|
try
|
|
{
|
|
// agent的运行目录可以选择硬编码完整路径,或根据center计算(center和agent的部署层次应该是一样)
|
|
string dir = "../log";
|
|
string logFullPath = Path.GetFullPath(dir);
|
|
foreach (string path in Directory.GetFiles(dir))
|
|
{
|
|
string name = Path.GetFileName(path);
|
|
if (name.Split('.')[0] != "smagent")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var file = FileUtils.CreateFileData(path, true);
|
|
if (file != null)
|
|
{
|
|
// 文件名加上host前缀作区分
|
|
file.fileName = SMAgentUtils.HostName + "_" + name;
|
|
|
|
// center和agent的部署层级应该是一样的, agent的log目录也是center的目录
|
|
file.writeFilePath = logFullPath;
|
|
|
|
fileList.Add(file);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Exception(e);
|
|
errorMsg = e.Message + "\n" + e.StackTrace;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private int GetPullFile(List<FileData> fileList)
|
|
{
|
|
try
|
|
{
|
|
/* push 命令支持绝对路径,如果是相对路径,那么是center和agent所在的bin目录为当前目录
|
|
* 所以最好用绝对路径,不容易出错
|
|
* -r 表示递归
|
|
* push 1.200.1 -r /data/mmogrun/publish/cfg/* /data/mmogrun/publish/cfg/
|
|
*/
|
|
|
|
//先处理一下参数
|
|
bool recursive = false;
|
|
List<string> pushfileParams = new List<string>();
|
|
string[] cmdParams = pullReq.CmdArgs.Split(' ');
|
|
for (int i = 1; i < cmdParams.Length; i++)
|
|
{
|
|
var param = cmdParams[i];
|
|
|
|
if (param == "-r")
|
|
{
|
|
recursive = true;
|
|
}
|
|
else
|
|
{
|
|
pushfileParams.Add(param);
|
|
}
|
|
}
|
|
|
|
if (pushfileParams.Count != 2)
|
|
{
|
|
TraceLog.Error("AgentFileTransMng.GetPullFile invalid param");
|
|
return -1;
|
|
}
|
|
|
|
string srcFile, srcfullPath;
|
|
string dstPath = pushfileParams[1];
|
|
string srcfilePath = pushfileParams[0];
|
|
|
|
//补一下'/',否则Path.GetFullPath结果不会带有'/'
|
|
if (dstPath[dstPath.Length - 1] != '/' && dstPath[dstPath.Length - 1] != '\\')
|
|
{
|
|
dstPath += '/';
|
|
}
|
|
|
|
string dstfullPath = Path.GetFullPath(dstPath);
|
|
|
|
int lastindex = srcfilePath.LastIndexOf('/');
|
|
if (lastindex == -1)
|
|
{
|
|
lastindex = srcfilePath.LastIndexOf('\\');
|
|
if (lastindex == -1)
|
|
{
|
|
TraceLog.Error("AgentFileTransMng.GetPullFile invalid srcpath {0}", srcfilePath);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
//源是个目录而不是文件名或通配符,那么在最后加个*上去,这样统一了
|
|
if (recursive && Directory.Exists(srcfilePath))
|
|
{
|
|
if (srcfilePath[srcfilePath.Length - 1] != '/' && srcfilePath[srcfilePath.Length - 1] != '\\')
|
|
{
|
|
srcfilePath += '/';
|
|
}
|
|
|
|
srcFile = "*";
|
|
srcfullPath = Path.GetFullPath(srcfilePath);
|
|
srcfullPath = Path.GetDirectoryName(srcfullPath);
|
|
}
|
|
else
|
|
{
|
|
string srcPath = srcfilePath.Substring(0, lastindex + 1);
|
|
srcFile = srcfilePath.Substring(lastindex + 1);
|
|
srcfullPath = Path.GetFullPath(srcPath);
|
|
srcfullPath = Path.GetDirectoryName(srcfullPath);
|
|
}
|
|
|
|
|
|
//说明只传一个文件
|
|
if (srcFile.Contains('*') == false)
|
|
{
|
|
var filefullpath = srcfullPath + "/" + srcFile;
|
|
var file = FileUtils.CreateFileData(filefullpath, true);
|
|
file.writeFilePath = dstfullPath;
|
|
fileList.Add(file);
|
|
|
|
TraceLog.Trace("AgentFileTransMng.GetPullFile add file to list, path {0} file {1}"
|
|
, file.readFilePath, file.fileName);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//根据通配符传送多个文件,先判断是否递归
|
|
SearchOption so = SearchOption.TopDirectoryOnly;
|
|
if (recursive)
|
|
{
|
|
so = SearchOption.AllDirectories;
|
|
}
|
|
|
|
foreach (string filefullpath in Directory.GetFiles(srcfullPath, srcFile, so))
|
|
{
|
|
var file = FileUtils.CreateFileData(filefullpath, true);
|
|
//判断是否子目录
|
|
file.writeFilePath = dstfullPath;
|
|
if (file.readFilePath != srcfullPath) //子目录
|
|
{
|
|
string addsubdir = file.readFilePath.Substring(srcfullPath.Length);
|
|
file.writeFilePath += addsubdir;
|
|
}
|
|
|
|
fileList.Add(file);
|
|
|
|
TraceLog.Trace("AgentFileTransMng.GetPullFile add file to list, path {0} file {1}"
|
|
, file.readFilePath, file.fileName);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
TraceLog.Exception(e);
|
|
errorMsg = e.Message + "\n" + e.StackTrace;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|