使用 HttpClient + System.Security.Cryptography。
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class LicenseClient
{
const string API_BASE = "https://你的域名";
const string USERNAME = "你的用户名";
const string APP_NAME = "a";
const string APP_KEY = "32位程序密钥";
static string Md5Sign(string act, string card, string mac, string app, long ts, string key)
{
var raw = $"{act}|{card}|{mac}|{app}|{ts}|{key}";
using var md5 = MD5.Create();
var bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(raw));
var sb = new StringBuilder();
foreach (var b in bytes) sb.Append(b.ToString("x2"));
return sb.ToString();
}
static async Task Call(string act, string card, string mac)
{
long ts = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
string sign = Md5Sign(act, card, mac, APP_NAME, ts, APP_KEY);
var url = $"{API_BASE}/kami/{USERNAME}/check.php" +
$"?act={act}&app={APP_NAME}&card={card}" +
$"&mac={mac}&sign={sign}&ts={ts}";
using var http = new HttpClient();
return await http.GetStringAsync(url);
}
static async Task Main()
{
string card = "ABCD-EFGH-JKLM-NPQR";
string mac = "MACHINE-CODE-HERE";
// 登录
var resp = await Call("login", card, mac);
Console.WriteLine(resp);
// 心跳循环
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(55));
var r = await Call("heartbeat", card, mac);
if (!r.Contains("\"code\":0")) { Console.WriteLine("心跳失败"); break; }
}
}
}