using System; using System.Configuration; using System.Net.Http; using System.Text; using System.Threading; using Newtonsoft.Json; using RevitHttpControl.Models; namespace RevitHttpControl.Services { /// /// 批处理任务结果回调服务 /// 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; } } } }