From 7be3c8edb4e68b25e87e99031e52e05aeb5fc493 Mon Sep 17 00:00:00 2001
From: handefeng <1030428966@qq.com>
Date: Thu, 5 Dec 2024 17:03:38 +0800
Subject: [PATCH] =?UTF-8?q?add=EF=BC=9Asoc=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Model/Services/SOCClientService.cs | 184 ++++++++++++++++++++++++++---
Model/Services/StatusCodes.cs | 32 +++++
Resource/Document/log.txt | 7 ++
SparkClient.csproj | 8 ++
SparkClient.sln.DotSettings.user | 2 +
5 files changed, 217 insertions(+), 16 deletions(-)
create mode 100644 Model/Services/StatusCodes.cs
create mode 100644 Resource/Document/log.txt
diff --git a/Model/Services/SOCClientService.cs b/Model/Services/SOCClientService.cs
index dffd822..85436fe 100644
--- a/Model/Services/SOCClientService.cs
+++ b/Model/Services/SOCClientService.cs
@@ -1,23 +1,62 @@
using Newtonsoft.Json;
using System;
+using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
+using HandyControl.Tools.Extension;
namespace SparkClient.Model.Services
{
+ ///
+ /// SOC 客户端服务类,用于与远程服务器进行交互,包括启动图片收集任务、获取图片、获取采集状态等操作。
+ ///
public class SOCClientService
{
+ // Log地址
+ private const string LogFilePath = @"..\..\..\Resource\Document\log.txt";
+ // Log格式
+ private const string LogMessageFormat = "[{0:yyyy-MM-dd HH:mm:ss.fff}] 发生异常: {1}{2}";
+
+ private static readonly Dictionary StatusDescriptions = new Dictionary
+ {
+ { "S000", "成功" },
+ { "S001", "采图正在进行中" },
+ { "S002", "缓存图片被清理(读取不够及时)" },
+ { "S003", "无法向单片机发送指令" },
+ { "S004", "单片机访问超时" },
+ { "S005", "单片机返回错误码" },
+ { "P001", "未找到切工仪" },
+ { "P002", "算法调用失败" }
+ };
+
+ ///
+ /// 基础URL,用于构建完整的API请求地址。
+ ///
private readonly string _baseUrl;
+
+ ///
+ /// 认证令牌,用于HTTP请求的认证。
+ ///
private readonly string _authToken;
+ ///
+ /// 构造函数,初始化基础URL和认证令牌。
+ ///
+ /// 基础URL
+ /// 认证令牌
public SOCClientService(string baseUrl, string authToken)
{
_baseUrl = baseUrl;
_authToken = authToken;
}
- // 通用GET请求方法
+ ///
+ /// 发送GET请求的通用方法。
+ ///
+ /// 请求的完整URL
+ /// HTTP响应
private async Task SendGetRequestAsync(string url)
{
using (var client = new HttpClient())
@@ -27,7 +66,11 @@ namespace SparkClient.Model.Services
}
}
- // 1. 启动图片收集任务
+ ///
+ /// 启动图片收集任务。
+ ///
+ /// 光照级别
+ /// 任务状态
public async Task CollectImagesAsync(int lightLevel)
{
string url = $"{_baseUrl}/collect_images?light_level={lightLevel}";
@@ -41,27 +84,55 @@ namespace SparkClient.Model.Services
}
else
{
- return "Error: " + response.StatusCode;
+ return "collect_images_Error: " + (int)response.StatusCode;
}
}
- // 2. 获取图片
- public async Task RetrieveImageAsync(int index)
+ ///
+ /// 获取指定索引的图片。
+ ///
+ /// 图片索引
+ /// 图片的字节数组
+ public async Task> RetrieveImageAsync(string savePath)
{
- string url = $"{_baseUrl}/retrieve_image/{index}";
- var response = await SendGetRequestAsync(url);
-
- if (response.IsSuccessStatusCode)
- {
- return await response.Content.ReadAsByteArrayAsync();
- }
- else
+ List imageNames = new List();
+ // 读取图片接口
+ int imageIndex = 0;
+ while (true)
{
- throw new Exception("Error retrieving image: " + response.StatusCode);
+ string url = $"{_baseUrl}/retrieve_image/{imageIndex}";
+ var response = await SendGetRequestAsync(url);
+ int status = (int)response.StatusCode;
+
+ if (status == 200)
+ {
+ byte[] imageBytes = await response.Content.ReadAsByteArrayAsync();
+ string fileName = Path.Combine(savePath, $"image_{imageIndex}.bmp");
+ // 图片名称List
+ imageNames.Add(Path.GetFileName(fileName));
+ // 保存图片
+ await File.WriteAllBytesAsync(fileName, imageBytes);
+ imageIndex++;
+ }
+ else if (status == 425)
+ {
+ await Task.Delay(1000);
+ }
+ else if (status == 410)
+ {
+ imageIndex++;
+ }
+ else if (status == 404)
+ {
+ return imageNames;
+ }
}
}
- // 3. 获取采集状态
+ ///
+ /// 获取图片采集状态。
+ ///
+ /// 采集状态
public async Task CollectStatusAsync()
{
string url = $"{_baseUrl}/collect_status";
@@ -75,14 +146,95 @@ namespace SparkClient.Model.Services
}
else
{
- return "Error: " + response.StatusCode;
+ return "collect_status_Error: " + (int)response.StatusCode;
+ }
+ }
+
+ ///
+ /// 处理图片收集、保存和状态检查。
+ ///
+ /// 光照级别
+ /// 图片保存路径
+ /// 操作结果
+ public async Task ProcessImageCollectionAsync(int lightLevel, string savePath)
+ {
+ try
+ {
+ // 清理 savePath 文件夹
+ if (Directory.Exists(savePath))
+ {
+ Directory.Delete(savePath, true);
+ }
+ Directory.CreateDirectory(savePath);
+
+ // 启动任务接口
+ string startStatus = await CollectImagesAsync(lightLevel);
+ if (startStatus != "S000")
+ {
+ // 启动任务失败
+ return JsonConvert.SerializeObject(new { status = startStatus, images = new List() });
+ }
+
+ // 读取图片接口
+ List imageNames = await RetrieveImageAsync(savePath);
+ if (imageNames.Count != 0)
+ {
+ // 采集状态接口
+ string acquisitionStatus = await CollectStatusAsync();
+ if (acquisitionStatus != "S000")
+ {
+ // 采集状态失败
+ return JsonConvert.SerializeObject(new { status = acquisitionStatus, images = new List() });
+
+ }
+ }
+ // 按下载时间排序图片名称
+ return JsonConvert.SerializeObject(new { status = "S000", images = imageNames });
+
+ }
+ catch (Exception e)
+ {
+ // 日志记录
+ // logger.Error(e, "发生异常");
+ string logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] 发生异常: {e.Message}{Environment.NewLine}";
+ File.AppendAllText(LogFilePath, logMessage);
+ return JsonConvert.SerializeObject(new { status = "P001", images = new List() });
+
+ }
+ }
+
+ ///
+ /// 根据状态码获取相应的描述信息。
+ /// 如果状态码在预定义的状态字典中存在,则返回对应的描述信息;
+ /// 否则返回“未知状态: [状态码]”。
+ ///
+ /// 状态码。
+ /// 状态描述信息。
+ private string GetDescription(string status)
+ {
+ if (StatusDescriptions.TryGetValue(status, out string description))
+ {
+ return description;
}
+ return "未知状态: " + status;
}
+
}
+
+ ///
+ /// 响应状态类,用于解析服务器返回的状态信息。
+ ///
public class ResponseStatus
{
+ ///
+ /// 状态码
+ ///
public string Status { get; set; }
+
+ ///
+ /// 状态消息
+ ///
public string Message { get; set; }
}
}
diff --git a/Model/Services/StatusCodes.cs b/Model/Services/StatusCodes.cs
new file mode 100644
index 0000000..f7209bd
--- /dev/null
+++ b/Model/Services/StatusCodes.cs
@@ -0,0 +1,32 @@
+namespace SparkClient.Model.Common
+{
+ ///
+ /// 存储状态码及其描述信息的常量类。
+ ///
+ public static class StatusCodes
+ {
+ // 成功
+ public const string S000 = "S000";
+
+ // 采图正在进行中
+ public const string S001 = "S001";
+
+ // 缓存图片被清理(读取不够及时)
+ public const string S002 = "S002";
+
+ // 无法向单片机发送指令
+ public const string S003 = "S003";
+
+ // 单片机访问超时
+ public const string S004 = "S004";
+
+ // 单片机返回错误码
+ public const string S005 = "S005";
+
+ // 未找到切工仪
+ public const string P001 = "P001";
+
+ // 算法调用失败
+ public const string P002 = "P002";
+ }
+}
\ No newline at end of file
diff --git a/Resource/Document/log.txt b/Resource/Document/log.txt
new file mode 100644
index 0000000..ea7f075
--- /dev/null
+++ b/Resource/Document/log.txt
@@ -0,0 +1,7 @@
+[2024-12-05 16:21:22.627] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000)
+[2024-12-05 16:42:38.854] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000)
+[2024-12-05 16:42:49.827] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000)
+[2024-12-05 16:50:48.304] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000)
+[2024-12-05 16:50:56.037] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000)
+[2024-12-05 16:51:04.013] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000)
+[2024-12-05 16:58:31.184] 发生异常: 由于目标计算机积极拒绝,无法连接。 (localhost:5000)
diff --git a/SparkClient.csproj b/SparkClient.csproj
index fd168fe..afdda84 100644
--- a/SparkClient.csproj
+++ b/SparkClient.csproj
@@ -30,6 +30,9 @@
Always
+
+ PreserveNewest
+
@@ -100,4 +103,9 @@
+
+
+
+
+
diff --git a/SparkClient.sln.DotSettings.user b/SparkClient.sln.DotSettings.user
index 15908bb..f3fef9c 100644
--- a/SparkClient.sln.DotSettings.user
+++ b/SparkClient.sln.DotSettings.user
@@ -7,6 +7,8 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded