using Newtonsoft.Json;
using System;
using System.Configuration;
using System.Data;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using HandyControl.Tools.Extension;
using log4net;
using SparkClient.Model.Common;
using SparkClient.Model.Entity.ApiEntity;
using SparkClient.Model.Helper;
namespace SparkClient.Model.Services
{
///
/// SOC 客户端服务类,用于与远程服务器进行交互,包括启动图片收集任务、获取图片、获取采集状态等操作。
///
public class SOCClientService
{
// Log地址
private const string LogFilePath = @"..\..\..\Resource\Document\log.txt";
private static readonly ILog Logger = LogManager.GetLogger(typeof(SOCClientService));
///
/// 基础URL,用于构建完整的API请求地址。
///
private readonly string? _baseUrl;
///
/// 认证令牌,用于HTTP请求的认证。
///
private readonly string _authToken;
///
/// 构造函数,初始化基础URL和认证令牌。
///
public SOCClientService()
{
//_baseUrl = "http://192.168.3.100:8080";
_baseUrl = ConfigurationManager.AppSettings["BaseUrl"];
_authToken = "your_basic_auth_token";
}
///
/// 发送GET请求的通用方法。
///
/// 请求的完整URL
/// HTTP响应
private async Task SendGetRequestAsync(string url)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Basic " + _authToken);
return await client.GetAsync(url);
}
}
///
/// 启动图片收集任务。
///
/// 任务状态
public async Task CollectImagesAsync()
{
try
{
// 光照度和半圆
int lightLevel = 0;
string halfCircle = string.Empty;
// 查询光照度和半圆配置
string sql = $"SELECT KEY, VALUE FROM CUTTER_CONFIG WHERE KEY IN ('light_level', 'half_circle')";
DataTable table = DataBaseHelper.ExecuteQuery(sql);
if (table == null || table.Rows.Count == 0)
{
throw new Exception("No data found for the specified keys.");
}
foreach (DataRow row in table.Rows)
{
string key = row["Key"].ToString() ?? string.Empty;
string value = row["Value"].ToString() ?? string.Empty;
if (key == "light_level" && int.TryParse(value, out int parsedLightLevel))
{
lightLevel = parsedLightLevel; // 光照度
}
else if (key == "half_circle")
{
halfCircle = value; // 半圆
}
}
string url = $"{_baseUrl}/collect_images?light_level={lightLevel}&half_circle={halfCircle}";
var response = await SendGetRequestAsync(url);
if (!response.IsSuccessStatusCode)
{
return new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List()};
}
var jsonResponse = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject(jsonResponse);
if (result == null)
{
return new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List()};
}
return new SocResultEntity { Status = result.Status, Images = new List() , DeviceId = result.device_id};
}
catch (Exception ex)
{
// 记录日志或进行其他处理
Console.WriteLine($"Error in DoSoc: {ex.Message}");
Logger.Warn($"Error in DoSoc: {ex.Message}");
// 或者使用日志框架记录日志
// logger.LogError(ex, "Error in DoSoc method.");
return new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List() , DeviceId = ""};
}
}
///
/// 获取指定索引的图片。
///
/// 保存图片路径
/// 图片的字节数组
public async Task> RetrieveImageAsync(string? savePath)
{
List imageNames = new List();
// 读取图片接口
int imageIndex = 0;
while (true)
{
string url = $"{_baseUrl}/retrieve_image/{imageIndex}";
try
{
var response = await SendGetRequestAsync(url);
int status = (int)response.StatusCode;
switch (status)
{
case 200:
byte[] imageBytes = await response.Content.ReadAsByteArrayAsync();
// 获取 Content-Type 头以确定图片格式
string contentType = response.Content.Headers.ContentType.MediaType;
string fileExtension = GetFileExtension(contentType);
string fileName = Path.Combine(savePath, $"image_{imageIndex}{fileExtension}");
// 图片名称List
imageNames.Add(Path.GetFileName(fileName));
// 保存图片
await File.WriteAllBytesAsync(fileName, imageBytes);
imageIndex++;
break;
case 425:
// 请求被锁定,等待一段时间后重试
await Task.Delay(1000);
break;
case 410:
// 资源已被永久删除,跳过当前索引
imageIndex++;
break;
case 404:
// 资源未找到,结束循环
return imageNames;
default:
// 其他状态码,记录警告并继续
Logger.Warn($"Unexpected status code: {status} for URL: {url}");
imageIndex++;
break;
}
}
catch (HttpRequestException ex)
{
// 捕获HTTP请求异常并记录错误信息
Logger.Error($"HTTP request failed for URL: {url}, Exception: {ex.Message}");
return imageNames;
}
catch (Exception ex)
{
// 捕获其他异常并记录错误信息,结束循环
Logger.Error($"An unexpected error occurred for URL: {url}, Exception: {ex.Message}");
return imageNames;
}
}
}
///
/// 获取图片采集状态。
///
/// 采集状态
public async Task CollectStatusAsync()
{
string url = $"{_baseUrl}/collect_status";
try
{
var response = await SendGetRequestAsync(url);
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject(jsonResponse);
return result.Status;
}
return StatusCodes.DeviceNotFound;
}
catch (HttpRequestException ex)
{
return StatusCodes.DeviceNotFound;
}
catch (JsonException ex)
{
return StatusCodes.DeviceNotFound;
}
catch (Exception ex)
{
return StatusCodes.DeviceNotFound;
}
}
///
/// 处理图片收集、保存和状态检查。
///
/// 操作结果
public async Task ProcessImageCollectionAsync()
{
try
{
// SOC接口
string? savePath = ConfigurationManager.AppSettings["ImageFileBasePath"];
// 清理 savePath 文件夹
if (Directory.Exists(savePath))
{
Directory.Delete(savePath, true);
}
Directory.CreateDirectory(savePath);
// 启动任务接口
SocResultEntity entity = await CollectImagesAsync();
// 成功
if (entity.Status != StatusCodes.Success)
{
// 启动任务失败
return new SocResultEntity { Status = entity.Status, Images = new List() };
}
// 读取图片接口
List imageNames = await RetrieveImageAsync(savePath);
// 采集状态接口
string acquisitionStatus = await CollectStatusAsync();
// 成功
if (acquisitionStatus != StatusCodes.Success)
{
// 采集状态失败
return new SocResultEntity { Status = acquisitionStatus, Images = new List() };
}
if (imageNames.Count == 0)
{
// 图片文件读取失败
return new SocResultEntity { Status = StatusCodes.ImageFileReadFailure, Images = new List() };
}
return new SocResultEntity { Status = acquisitionStatus, Images = imageNames, DeviceId = entity.DeviceId};
}
catch (Exception e)
{
// 日志记录
// logger.Error(e, "发生异常");
string logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] 发生异常: {e.Message}{Environment.NewLine}";
Logger.Error(logMessage);
return new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List() };
}
}
///
/// 根据给定的 MIME 类型获取对应的文件扩展名。
///
/// HTTP 响应中的 Content-Type 头字段,表示内容的 MIME 类型。
/// 与 MIME 类型对应的文件扩展名。
/// 当传入的 MIME 类型不受支持时抛出此异常。
private string GetFileExtension(string contentType)
{
switch (contentType.ToLower())
{
case "image/bmp":
return ".bmp";
case "image/jpg":
return ".jpg";
case "image/png":
return ".png";
default:
throw new InvalidOperationException($"Unsupported content type: {contentType}");
}
}
}
///
/// 响应状态类,用于解析服务器返回的状态信息。
///
public class ResponseStatus
{
///
/// 状态码
///
public string Status { get; set; }
///
/// 状态消息
///
public string Message { get; set; }
///
/// 机器号
///
public string device_id { get; set; }
}
}