背景
最近的一个项目,涉及将客户端执行后的结果回传给服务端,便于对客户端执行的信息进行统一的管理。
思路
1 执行服务器执行查询成功
2 执行服务器在本地生成序列化的xml文件
3 执行服务器发送线程调用远程WebService将本地结果文件读取为字节流发送到服务器;如果成功,则删除本地结果文件;否则,继续回发,直到成功为止。--消息队列本质。
实现
1 执行服务器执行查询成功
2 执行服务器在本地生成序列化的xml文件
//把任务结果信息序列化写入文件
this.WriteResultToFile(pmqPath, info, result);
3 执行服务器发送线程调用远程WebService将本地结果文件读取为字节流发送到服务器
1 从本地文件读取字节流
while (true)
{
try
{
pmqPath = Common.GetAppSettings(PMQPathKey);
if (!Directory.Exists(pmqPath))
{
Directory.CreateDirectory(pmqPath);
}
pmqDirectInfo = new DirectoryInfo(pmqPath);
XmlSerializer xs = new XmlSerializer(typeof(TaskExecuteQueueExtendInfo));
files = pmqDirectInfo.GetFiles("*" + PMQExtendFileName);
Array.Sort<FileInfo>(files, delegate(FileInfo filel, FileInfo filer)
{
return int.Parse(Path.GetFileNameWithoutExtension(filel.Name)).CompareTo(int.Parse(Path.GetFileNameWithoutExtension(filer.Name)));
});
planTaskExcuteQueue = new PlanTaskExecuteQueue();
planTaskExcuteQueue.Timeout = Convert.ToInt32(Common.GetAppSettings(WebServiceTimeOutKey));
foreach (FileInfo file in files)
{
//得到任务队列扩展信息
using (Stream stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
taskExecuteQueueExtendInfo = (TaskExecuteQueueExtendInfo)xs.Deserialize(stream);
}
if (taskExecuteQueueExtendInfo == null)
{
continue;
}
// 回发执行结果
try
{
booleanResult = planTaskExcuteQueue.ProcessTaskExecutedResult(taskExecuteQueueExtendInfo);
}
catch (Exception ex)
{
MessageQueue.Instance.InsertMessage(ex.Message);
}
// 如果成功则删除消息文件
if (booleanResult != null && booleanResult.IsSuccess)
{
file.Delete();
}
}
}
catch (Exception ex)
{
MessageQueue.Instance.InsertMessage(ex.Message);
}
Thread.Sleep(Convert.ToInt32(Common.GetAppSettings(PMQThreadSleepTimeKey)));
}
2 通过WebService传到服务端(回发执行提示信息与结果)
提示信息(后面不写:在服务端完成了记日志的功能) [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/ProcessTaskExecutedResult", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public BooleanResult ProcessTaskExecutedResult(TaskExecuteQueueExtendInfo taskExecuteQueueInfo) {
object[] results = this.Invoke("ProcessTaskExecutedResult", new object[] {
taskExecuteQueueInfo});
return ((BooleanResult)(results[0]));
}
回发结果文件
/// <summary>
/// 处理任务生成的文件
/// </summary>
/// <param name="fileParameter">生成文件参数</param>
/// <param name="fileContent">文件内容</param>
/// <returns>是否成功</returns>
[WebMethod(Description = "处理任务生成的文件")]
public BooleanResult ProcessTaskGeneratoredFile(GeneratorTaskReportInfo generatorReportInfo, byte[] fileContent)
{
PlanDispatchService dispatchService = new PlanDispatchService();
return dispatchService.ProcessTaskGeneratoredFile(generatorReportInfo, fileContent);
}
扩展:将信息写进数据库
taskQueueReportInfo = new TaskQueueReportInfo();
taskQueueReportInfo.FileName = generatorReportInfo.FileName;
taskQueueReportInfo.SendUserAccount = sendAccount;
taskQueueReportInfo.TaskPlanQueueCode = generatorReportInfo.TaskPlanQueueCode;
taskQueueReportInfo.FileContent = fileContent;
taskQueueReport.CreateTaskQueueReport(taskQueueReportInfo);
}
4 统一后台下载(扩展):
if (e.CommandName == "DownLoad")
{
int code = Convert.ToInt32(e.CommandArgument);
GenericResult<TaskQueueReportInfo> reportResult = planTaskService.GetReportByCode(code);
if (reportResult.IsSuccess)
{
this.GenerateCSV(reportResult.Value.FileName, reportResult.Value.FileContent);
}
else
{
JsHelper.JsAlert(this, reportResult.Message, false);
return;
}
}
private void GenerateCSV(string fileName, byte[] fileContent)
{
if (string.IsNullOrEmpty(fileName) || fileContent == null)
{
return;
}
string extendName = Path.GetExtension(fileName);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Charset = "utf-8";
HttpContext.Current.Response.ContentType = extendName;
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
HttpContext.Current.Response.BinaryWrite(fileContent);
HttpContext.Current.Response.End();
}