TellmeRevitPluging/Services/TaskCallbackService.cs

101 lines
3.4 KiB
C#

using System;
using System.Configuration;
using System.Net.Http;
using System.Text;
using System.Threading;
using Newtonsoft.Json;
using RevitHttpControl.Models;
namespace RevitHttpControl.Services
{
/// <summary>
/// 批处理任务结果回调服务
/// </summary>
public static class TaskCallbackService
{
private const string DefaultEndpointPath = "/api/v1/plugin-callbacks/task-result";
private const string DefaultSoftwareId = "revit";
private static readonly TimeSpan[] RetryDelays =
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(3),
TimeSpan.FromSeconds(5)
};
public static void NotifyTaskResult(TaskStatusResponse task)
{
if (task == null || (task.Status != TaskStatus.Completed && task.Status != TaskStatus.Failed))
{
return;
}
var baseAddress = ConfigurationManager.AppSettings["PluginCallbackBaseUrl"];
var token = ConfigurationManager.AppSettings["PluginCallbackToken"];
var softwareId = ConfigurationManager.AppSettings["PluginSoftwareId"];
if (string.IsNullOrWhiteSpace(baseAddress) || string.IsNullOrWhiteSpace(token))
{
return;
}
if (string.IsNullOrWhiteSpace(softwareId))
{
softwareId = DefaultSoftwareId;
}
var callbackUrl = $"{baseAddress.TrimEnd('/')}{DefaultEndpointPath}";
var payload = new TaskResultCallbackRequest
{
ExecutionId = task.ExecutionId,
SoftwareId = softwareId,
Status = task.Status == TaskStatus.Completed ? "success" : "failed",
ErrorMessage = task.Status == TaskStatus.Failed
? (string.IsNullOrWhiteSpace(task.ErrorMessage) ? "UNKNOWN_ERROR" : task.ErrorMessage)
: null,
Result = task.Status == TaskStatus.Completed ? (task.Result ?? new { }) : new { },
FinishedAt = (task.CompletedAt ?? DateTime.UtcNow).ToString("o"),
Token = token
};
SendWithRetry(callbackUrl, payload);
}
private static void SendWithRetry(string callbackUrl, TaskResultCallbackRequest payload)
{
var json = JsonConvert.SerializeObject(payload);
using (var httpClient = new HttpClient())
{
if (Post(httpClient, callbackUrl, json))
{
return;
}
foreach (var delay in RetryDelays)
{
Thread.Sleep(delay);
if (Post(httpClient, callbackUrl, json))
{
return;
}
}
}
}
private static bool Post(HttpClient httpClient, string callbackUrl, string json)
{
try
{
using (var content = new StringContent(json, Encoding.UTF8, "application/json"))
using (var response = httpClient.PostAsync(callbackUrl, content).GetAwaiter().GetResult())
{
return response.IsSuccessStatusCode;
}
}
catch
{
return false;
}
}
}
}