414 lines
15 KiB
C#
414 lines
15 KiB
C#
using MessagePack;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
using Microsoft.Extensions.Hosting;
|
||
using Newtonsoft.Json;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Net.Http;
|
||
using System.Net.WebSockets;
|
||
using System.Security.Cryptography;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace WasteConsoleTest
|
||
{
|
||
class Program
|
||
{
|
||
private static WSocketClientHelp wSocketClient = null;
|
||
public static string Secret = "0eMqhAjefL0loGhH";
|
||
public static string SecretHash = "d28a95b3d5d85ef0";
|
||
public static string SocketURL = "wss://api.device.suzhou.ljflytjl.cn/device_rpc";
|
||
static async Task Main(string[] args)
|
||
{
|
||
var builder = new HostBuilder().ConfigureServices((hostContext, services) =>
|
||
{
|
||
services.AddHttpClient();
|
||
services.AddTransient<IMyService, MyService>();
|
||
}).UseConsoleLifetime();
|
||
var host = builder.Build();
|
||
wSocketClient = new WSocketClientHelp(SocketURL);
|
||
wSocketClient.OnOpen -= WSocketClient_OnOpen;
|
||
wSocketClient.OnMessage -= WSocketClient_OnMessage;
|
||
wSocketClient.OnClose -= WSocketClient_OnClose;
|
||
wSocketClient.OnError -= WSocketClient_OnError;
|
||
|
||
wSocketClient.OnOpen += WSocketClient_OnOpen;
|
||
wSocketClient.OnMessage += WSocketClient_OnMessage;
|
||
wSocketClient.OnClose += WSocketClient_OnClose;
|
||
wSocketClient.OnError += WSocketClient_OnError;
|
||
wSocketClient.Open();
|
||
var myService = host.Services.GetRequiredService<IMyService>();
|
||
// SetTimeOut();
|
||
while (true)
|
||
{
|
||
string cmd = Console.ReadLine();
|
||
//退出
|
||
if (cmd == "exit")
|
||
{
|
||
Console.WriteLine("退出请求");
|
||
wSocketClient.Close();
|
||
break;
|
||
}
|
||
else
|
||
//测试sayhello
|
||
if (cmd.ToLower() == "sayhello")
|
||
{
|
||
var senddata = @"{
|
||
""type"": 1,
|
||
""invocationId"": ""Nil"",
|
||
""target"": ""sayHello"",
|
||
""arguments"": [
|
||
""Hello Test Message""
|
||
]
|
||
}";
|
||
wSocketClient.Send(senddata);
|
||
}
|
||
//获取token
|
||
else if (cmd.ToLower() == "gettoken")
|
||
{
|
||
var senddata = @"{
|
||
""type"": 1,
|
||
""invocationId"": ""Nil"",
|
||
""target"": ""getToken"",
|
||
""arguments"": [
|
||
""sz_data""
|
||
]
|
||
}";
|
||
wSocketClient.Send(senddata);
|
||
}
|
||
//测试token的有效期
|
||
else if (cmd.ToLower() == "testtoken")
|
||
{
|
||
await myService.TestTokenAsync();
|
||
}
|
||
//测试上报
|
||
else if (cmd.ToLower() == "postdata")
|
||
{
|
||
await myService.Garbages();
|
||
}
|
||
}
|
||
}
|
||
private static void WSocketClient_OnError(object sender, Exception ex)
|
||
{
|
||
Console.WriteLine($"发生异常:{ex.Message}");
|
||
}
|
||
|
||
private static void WSocketClient_OnClose(object sender, EventArgs e)
|
||
{
|
||
Console.WriteLine($"已关闭");
|
||
}
|
||
|
||
private static void WSocketClient_OnMessage(object sender, string data)
|
||
{
|
||
//处理的消息错误将会忽略
|
||
try
|
||
{
|
||
//查看数据是否有token
|
||
var jsondata = JsonConvert.DeserializeObject<ResponseData>(data);
|
||
if (jsondata != null && jsondata.type == 1 && !string.IsNullOrEmpty(jsondata.target) && jsondata.target.ToLower() == "token" && jsondata.arguments != null && jsondata.arguments.Count == 1)
|
||
{
|
||
var token = jsondata.arguments.First();
|
||
//保存token到文件中
|
||
var path = AppDomain.CurrentDomain.BaseDirectory + "File";
|
||
var filePath = path + @"\token.txt";
|
||
if (!Directory.Exists(path))
|
||
{
|
||
Directory.CreateDirectory(path);
|
||
}
|
||
if (File.Exists(filePath))
|
||
{
|
||
File.Delete(filePath);
|
||
}
|
||
using (var fileStream = new FileStream(filePath, FileMode.CreateNew))
|
||
{
|
||
byte[] content = Encoding.UTF8.GetBytes(token);
|
||
fileStream.Write(content, 0, content.Length);
|
||
}
|
||
}
|
||
//如果收到的消息为type=6心跳包,需要响应Pong
|
||
if(jsondata !=null && jsondata.type == 6)
|
||
{
|
||
var senddata = @"{
|
||
""type"": 6
|
||
}";
|
||
wSocketClient.Send(senddata);
|
||
}
|
||
Console.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")},收到的消息:{data}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
}
|
||
|
||
}
|
||
|
||
public interface IMyService
|
||
{
|
||
/// <summary>
|
||
/// 测试token有效期
|
||
/// </summary>
|
||
Task TestTokenAsync();
|
||
/// <summary>
|
||
/// 传送垃圾数据
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
Task Garbages();
|
||
}
|
||
|
||
public class MyService : IMyService
|
||
{
|
||
private readonly IHttpClientFactory _clientFactory;
|
||
|
||
public MyService(IHttpClientFactory clientFactory)
|
||
{
|
||
_clientFactory = clientFactory;
|
||
}
|
||
/// <summary>
|
||
/// 传送垃圾数据
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task Garbages()
|
||
{
|
||
try
|
||
{
|
||
string token = gettoken();
|
||
if (!string.IsNullOrEmpty(token))
|
||
{
|
||
int timestamp = GetTimestamp();
|
||
DateTime testtime = DateTime.Parse("2021-08-22 20:00:00");
|
||
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(testtime);
|
||
DateTime utcStartTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||
int scantime= timestamp = Convert.ToInt32((utcTime - utcStartTime).TotalSeconds);
|
||
|
||
var garbageC2SDto = new GarbageC2SDto
|
||
{
|
||
weight = 50.25,
|
||
trash = "251658245",
|
||
scanningTime = scantime,
|
||
d_status = 0,
|
||
type = 1
|
||
};
|
||
int nonce = GetNonce();
|
||
string[] paramlist = new string[] {
|
||
garbageC2SDto.weight.ToString(),garbageC2SDto.trash,garbageC2SDto.type.ToString(),garbageC2SDto.scanningTime.ToString(),garbageC2SDto.d_status.ToString()
|
||
};
|
||
string sign = GetUserApiSign(Secret, paramlist);
|
||
var request = new HttpRequestMessage(HttpMethod.Post,
|
||
"https://api.data.suzhou.ljflytjl.cn/api/Garbages");
|
||
request.Headers.Add("Authorization", $"Bearer {token}");
|
||
request.Headers.Add("secret", Secret);
|
||
request.Headers.Add("nonce", nonce.ToString());
|
||
request.Headers.Add("time", timestamp.ToString());
|
||
request.Headers.Add("sign", sign);
|
||
var message = JsonConvert.SerializeObject(garbageC2SDto);
|
||
request.Content = new StringContent(message, Encoding.UTF8, "application/json");
|
||
var client = _clientFactory.CreateClient();
|
||
var response = await client.SendAsync(request);
|
||
var result = await response.Content.ReadAsStringAsync();
|
||
if (response.IsSuccessStatusCode)
|
||
{
|
||
Console.WriteLine($"上报成功:{result}");
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine($"上报失败:{response.StatusCode},{result}");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Console.Write("token未找到");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试token有效期
|
||
/// </summary>
|
||
public async Task TestTokenAsync()
|
||
{
|
||
var request = new HttpRequestMessage(HttpMethod.Get,
|
||
"https://api.data.suzhou.ljflytjl.cn/api/hello/device");
|
||
string token = gettoken();
|
||
if (!string.IsNullOrEmpty(token))
|
||
{
|
||
request.Headers.Add("Authorization", $"Bearer {token}");
|
||
var client = _clientFactory.CreateClient();
|
||
var response = await client.SendAsync(request);
|
||
var result = await response.Content.ReadAsStringAsync();
|
||
if (response.IsSuccessStatusCode)
|
||
{
|
||
Console.WriteLine($"token可用:{result}");
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine($"token已过期:{response.StatusCode},{result}");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Console.Write("token未找到");
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 获取时间戳
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private int GetTimestamp()
|
||
{
|
||
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now);
|
||
DateTime utcStartTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||
int timestamp = Convert.ToInt32((utcTime-utcStartTime).TotalSeconds);
|
||
return timestamp;
|
||
}
|
||
/// <summary>
|
||
/// 获取随机数
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public int GetNonce()
|
||
{
|
||
var random = new Random();
|
||
int nonce = random.Next(1, Int32.MaxValue);
|
||
return nonce;
|
||
}
|
||
/// <summary>
|
||
/// 获取签名
|
||
/// </summary>
|
||
/// <param name="secret"></param>
|
||
/// <param name="dataparams"></param>
|
||
/// <returns></returns>
|
||
public string GetUserApiSign(string secret, params string[] dataparams)
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
string ApiSecret = "EtifGTppTL0TTjie";
|
||
if (dataparams != null && dataparams.Length > 0)
|
||
{
|
||
foreach (var item in dataparams)
|
||
{
|
||
sb.Append(item);
|
||
}
|
||
}
|
||
if (!string.IsNullOrEmpty(secret))
|
||
{
|
||
sb.Append(secret);
|
||
}
|
||
else
|
||
{
|
||
sb.Append(ApiSecret);
|
||
}
|
||
string str = sb.ToString();
|
||
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
|
||
string sign = System.BitConverter.ToString(md5.ComputeHash(System.Text.UTF8Encoding.Default.GetBytes(str)), 4, 8).Replace("-", "");
|
||
sign = sign.ToLower();
|
||
return sign;
|
||
}
|
||
/// <summary>
|
||
/// 获取token
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private string gettoken()
|
||
{
|
||
var filePath = AppDomain.CurrentDomain.BaseDirectory + @"File\token.txt";
|
||
string token = string.Empty;
|
||
if (File.Exists(filePath))
|
||
{
|
||
token = File.ReadAllText(filePath);
|
||
}
|
||
return token;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 向服务端推送测试用垃圾采集数据
|
||
/// </summary>
|
||
public class GarbageC2SDto //客户端向服务端请求的DTO
|
||
{
|
||
/// <summary>
|
||
/// 垃圾称重数据,64位浮点进度,单位为千克
|
||
/// </summary>
|
||
public double weight { get; set; }
|
||
/// <summary>
|
||
/// 垃圾桶编码
|
||
/// </summary>
|
||
public string trash { get; set; }
|
||
/// <summary>
|
||
/// 垃圾类型,缺省类型 : 0,厨余垃圾 : 1,可回收物 : 2,有害垃圾 : 3,其他垃圾 : 4
|
||
/// </summary>
|
||
|
||
public int type { get; set; }
|
||
/// <summary>
|
||
/// 数据扫描时间,UNIX时间戳
|
||
/// </summary>
|
||
public int scanningTime { get; set; }
|
||
/// <summary>
|
||
/// 设备状态,使用中 : 0:使用中,异常 : 1,检修 : 2,检修结束 : 3,启用 : 4,未知 : 5
|
||
/// </summary>
|
||
public int d_status { get; set; }
|
||
}
|
||
/// <summary>
|
||
/// 响应的数据
|
||
/// </summary>
|
||
public class ResponseData
|
||
{
|
||
/// <summary>
|
||
/// 类型,6-心跳包,1-token,3-其他
|
||
/// </summary>
|
||
public int type { get; set; }
|
||
/// <summary>
|
||
/// 请求id
|
||
/// </summary>
|
||
public string invocationId { get; set; }
|
||
/// <summary>
|
||
/// 结果
|
||
/// </summary>
|
||
public string result { get; set; }
|
||
/// <summary>
|
||
/// 目标
|
||
/// </summary>
|
||
public string target { get; set; }
|
||
/// <summary>
|
||
/// 参数
|
||
/// </summary>
|
||
public List<string> arguments { get; set; }
|
||
}
|
||
|
||
private static void WSocketClient_OnOpen(object sender, EventArgs e)
|
||
{
|
||
Console.WriteLine($"已连接");
|
||
}
|
||
public static void SetTimeOut()
|
||
{
|
||
Task.Run(() =>
|
||
{
|
||
DateTime startime = DateTime.Now;
|
||
while (true)
|
||
{
|
||
if(wSocketClient.State == WebSocketState.Open)
|
||
{
|
||
if ((DateTime.Now - startime).TotalSeconds >= 15)
|
||
{
|
||
//发送心跳包
|
||
var message = @"{
|
||
""type"": 6
|
||
}";
|
||
wSocketClient.Send(message);
|
||
startime = DateTime.Now;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
private static byte[] RemoveSeparator(byte[] data)
|
||
{
|
||
List<byte> t = new List<byte>(data);
|
||
t.Remove(0x1e);
|
||
return t.ToArray();
|
||
}
|
||
}
|
||
}
|