LicenseManger/sdk/csharp/DeviceSDK.cs

220 lines
6.7 KiB
C#

using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace DeviceSDK
{
public class DeviceClient : IDisposable
{
private readonly string _baseUrl;
private readonly string _encryptKey;
private readonly HttpClient _httpClient;
private bool _disposed;
public DeviceClient(string baseUrl, string encryptKey)
{
_baseUrl = baseUrl.TrimEnd('/');
_encryptKey = encryptKey;
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(30)
};
}
// 设备注册
public async Task<DeviceRegisterResponse> RegisterDeviceAsync(DeviceRegisterRequest request)
{
try
{
var response = await PostAsync("/api/devices/register", request);
return JsonSerializer.Deserialize<DeviceRegisterResponse>(response);
}
catch (Exception ex)
{
throw new DeviceSDKException("设备注册失败", ex);
}
}
// 设备验证
public async Task<DeviceValidateResponse> ValidateDeviceAsync(string uid)
{
try
{
var response = await GetAsync($"/api/devices/{uid}/validate");
var result = JsonSerializer.Deserialize<ApiResponse>(response);
if (result.Code != 0)
{
throw new DeviceSDKException(result.Error);
}
var decrypted = DecryptResponse(result.Data);
return JsonSerializer.Deserialize<DeviceValidateResponse>(decrypted);
}
catch (Exception ex)
{
throw new DeviceSDKException("设备验证失败", ex);
}
}
// 更新启动次数
public async Task<StartCountResponse> UpdateStartCountAsync(string uid)
{
try
{
var response = await PostAsync($"/api/devices/{uid}/start", null);
return JsonSerializer.Deserialize<StartCountResponse>(response);
}
catch (Exception ex)
{
throw new DeviceSDKException("更新启动次数失败", ex);
}
}
// 绑定授权码
public async Task BindLicenseAsync(string uid, string licenseCode)
{
try
{
var request = new { license_code = licenseCode };
var response = await PostAsync($"/api/devices/{uid}/license", request);
var result = JsonSerializer.Deserialize<ApiResponse>(response);
if (result.Code != 0)
{
throw new DeviceSDKException(result.Error);
}
}
catch (Exception ex)
{
throw new DeviceSDKException("绑定授权码失败", ex);
}
}
private async Task<string> GetAsync(string path)
{
var response = await _httpClient.GetAsync(_baseUrl + path);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
private async Task<string> PostAsync(string path, object data)
{
var content = data == null ? null :
new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(_baseUrl + path, content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
private string DecryptResponse(string encrypted)
{
try
{
var cipherBytes = Convert.FromBase64String(encrypted);
var keyBytes = Encoding.UTF8.GetBytes(_encryptKey);
using var aes = Aes.Create();
aes.Key = keyBytes;
var iv = new byte[16];
Array.Copy(cipherBytes, 0, iv, 0, 16);
aes.IV = iv;
using var decryptor = aes.CreateDecryptor();
var cipher = new byte[cipherBytes.Length - 16];
Array.Copy(cipherBytes, 16, cipher, 0, cipher.Length);
var plainBytes = decryptor.TransformFinalBlock(cipher, 0, cipher.Length);
return Encoding.UTF8.GetString(plainBytes);
}
catch (Exception ex)
{
throw new DeviceSDKException("解密响应失败", ex);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_httpClient?.Dispose();
}
_disposed = true;
}
}
}
// 请求和响应模型
public class DeviceRegisterRequest
{
public string Uid { get; set; }
public string DeviceModel { get; set; }
public string LicenseCode { get; set; }
}
public class DeviceRegisterResponse
{
public int Code { get; set; }
public string Message { get; set; }
public DeviceRegisterData Data { get; set; }
}
public class DeviceRegisterData
{
public string Uid { get; set; }
public string DeviceModel { get; set; }
public string Status { get; set; }
}
public class DeviceValidateResponse
{
public string Status { get; set; }
public string LicenseType { get; set; }
public DateTime ExpireTime { get; set; }
public int StartCount { get; set; }
public int MaxUses { get; set; }
public long Timestamp { get; set; }
}
public class StartCountResponse
{
public int Code { get; set; }
public string Message { get; set; }
public StartCountData Data { get; set; }
}
public class StartCountData
{
public int StartCount { get; set; }
public string Status { get; set; }
public DateTime LastActiveAt { get; set; }
}
internal class ApiResponse
{
public int Code { get; set; }
public string Error { get; set; }
public string Data { get; set; }
}
// 自定义异常
public class DeviceSDKException : Exception
{
public DeviceSDKException(string message) : base(message) { }
public DeviceSDKException(string message, Exception innerException)
: base(message, innerException) { }
}
}