websocket测试控制台
This commit is contained in:
parent
6a221c14ba
commit
a70384370a
|
|
@ -25,3 +25,5 @@
|
||||||
/Waste.Web.Entry/bin
|
/Waste.Web.Entry/bin
|
||||||
/Waste.Web.Entry/obj
|
/Waste.Web.Entry/obj
|
||||||
/.vs
|
/.vs
|
||||||
|
/WasteConsoleTest/WasteConsoleTest/obj
|
||||||
|
/WasteConsoleTest/WasteConsoleTest/bin
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Waste.Socket", "Waste.Socke
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Waste.MessageHandler", "Waste.MessageHandler\Waste.MessageHandler.csproj", "{49EB30D4-FEB7-42FB-87A1-BE0440413392}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Waste.MessageHandler", "Waste.MessageHandler\Waste.MessageHandler.csproj", "{49EB30D4-FEB7-42FB-87A1-BE0440413392}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WasteConsoleTest", "WasteConsoleTest\WasteConsoleTest\WasteConsoleTest.csproj", "{AB59B811-AADC-439B-9394-73CFF8F64C6F}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -67,6 +69,10 @@ Global
|
||||||
{49EB30D4-FEB7-42FB-87A1-BE0440413392}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{49EB30D4-FEB7-42FB-87A1-BE0440413392}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{49EB30D4-FEB7-42FB-87A1-BE0440413392}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{49EB30D4-FEB7-42FB-87A1-BE0440413392}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{49EB30D4-FEB7-42FB-87A1-BE0440413392}.Release|Any CPU.Build.0 = Release|Any CPU
|
{49EB30D4-FEB7-42FB-87A1-BE0440413392}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{AB59B811-AADC-439B-9394-73CFF8F64C6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{AB59B811-AADC-439B-9394-73CFF8F64C6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{AB59B811-AADC-439B-9394-73CFF8F64C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{AB59B811-AADC-439B-9394-73CFF8F64C6F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -81,6 +87,7 @@ Global
|
||||||
{AE2A0447-5722-4D5B-89A5-6355E29FB706} = {A10953C4-FF58-42A1-AAEF-7B68018F5EDB}
|
{AE2A0447-5722-4D5B-89A5-6355E29FB706} = {A10953C4-FF58-42A1-AAEF-7B68018F5EDB}
|
||||||
{82C5EF90-C84C-4A83-A732-B82E0E429BDF} = {A10953C4-FF58-42A1-AAEF-7B68018F5EDB}
|
{82C5EF90-C84C-4A83-A732-B82E0E429BDF} = {A10953C4-FF58-42A1-AAEF-7B68018F5EDB}
|
||||||
{49EB30D4-FEB7-42FB-87A1-BE0440413392} = {A10953C4-FF58-42A1-AAEF-7B68018F5EDB}
|
{49EB30D4-FEB7-42FB-87A1-BE0440413392} = {A10953C4-FF58-42A1-AAEF-7B68018F5EDB}
|
||||||
|
{AB59B811-AADC-439B-9394-73CFF8F64C6F} = {A10953C4-FF58-42A1-AAEF-7B68018F5EDB}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {086B267B-9152-4816-8D48-30032ACB8A2C}
|
SolutionGuid = {086B267B-9152-4816-8D48-30032ACB8A2C}
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.31402.337
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WasteConsoleTest", "WasteConsoleTest\WasteConsoleTest.csproj", "{E365B702-88E9-4961-A29E-641BB7E1CE5A}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E365B702-88E9-4961-A29E-641BB7E1CE5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E365B702-88E9-4961-A29E-641BB7E1CE5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E365B702-88E9-4961-A29E-641BB7E1CE5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E365B702-88E9-4961-A29E-641BB7E1CE5A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {904AE273-F940-4429-A69A-26F4D2705412}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
|
@ -0,0 +1,395 @@
|
||||||
|
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 = "g8OEiOAaKjYK38aj";
|
||||||
|
public static string SecretHash = "9729e43752011ad4";
|
||||||
|
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("wss://api.device.suzhou.ljflytjl.cn/device_rpc");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
var garbageC2SDto = new GarbageC2SDto
|
||||||
|
{
|
||||||
|
weight = 10.01,
|
||||||
|
trash = "251658245",
|
||||||
|
scanningTime = timestamp,
|
||||||
|
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 (wSocketClient.State == WebSocketState.Open)
|
||||||
|
{
|
||||||
|
if ((DateTime.Now - startime).TotalSeconds >= 13)
|
||||||
|
{
|
||||||
|
//发送心跳包
|
||||||
|
var message = @"{
|
||||||
|
""type"": 6
|
||||||
|
}";
|
||||||
|
wSocketClient.Send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private static byte[] RemoveSeparator(byte[] data)
|
||||||
|
{
|
||||||
|
List<byte> t = new List<byte>(data);
|
||||||
|
t.Remove(0x1e);
|
||||||
|
return t.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,239 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.WebSockets;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WasteConsoleTest
|
||||||
|
{
|
||||||
|
public class WSocketClientHelp
|
||||||
|
{
|
||||||
|
ClientWebSocket ws = null;
|
||||||
|
Uri uri = null;
|
||||||
|
bool isUserClose = false;//是否最后由用户手动关闭
|
||||||
|
public static string Secret = "g8OEiOAaKjYK38aj";
|
||||||
|
public static string SecretHash = "9729e43752011ad4";
|
||||||
|
public static string deviceid = "08d95bb6-a0f1-4964-85ac-9786b3571656";
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
/// WebSocket状态
|
||||||
|
/// </summary>
|
||||||
|
public WebSocketState? State { get => ws?.State; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 包含一个数据的事件
|
||||||
|
/// </summary>
|
||||||
|
public delegate void MessageEventHandler(object sender, string data);
|
||||||
|
public delegate void ErrorEventHandler(object sender, Exception ex);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接建立时触发
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnOpen;
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端接收服务端数据时触发
|
||||||
|
/// </summary>
|
||||||
|
public event MessageEventHandler OnMessage;
|
||||||
|
/// <summary>
|
||||||
|
/// 通信发生错误时触发
|
||||||
|
/// </summary>
|
||||||
|
public event ErrorEventHandler OnError;
|
||||||
|
/// <summary>
|
||||||
|
/// 连接关闭时触发
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnClose;
|
||||||
|
|
||||||
|
public WSocketClientHelp(string wsUrl)
|
||||||
|
{
|
||||||
|
uri = new Uri(wsUrl);
|
||||||
|
ws = new ClientWebSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打开链接
|
||||||
|
/// </summary>
|
||||||
|
public void Open()
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
if (ws.State == WebSocketState.Connecting || ws.State == WebSocketState.Open)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string netErr = string.Empty;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//初始化链接
|
||||||
|
isUserClose = false;
|
||||||
|
ws = new ClientWebSocket();
|
||||||
|
// ws.Options.AddSubProtocol("protocol1"); //使用的协议
|
||||||
|
ws.Options.SetRequestHeader("device", deviceid); //设备ID
|
||||||
|
ws.Options.SetRequestHeader("secret", SecretHash); //设备secrethash
|
||||||
|
ws.Options.SetRequestHeader("time", GetTimestamp().ToString()); //时间戳
|
||||||
|
ws.Options.SetRequestHeader("os", "12"); //操作系统,Android ArmV7
|
||||||
|
ws.Options.SetRequestHeader("script", "2"); //设备支持的脚本语言运行环境,1-lua5.4 2-javascript
|
||||||
|
ws.Options.SetRequestHeader("baseProgrameLang", "10"); //宿主程序语言,java
|
||||||
|
ws.Options.SetRequestHeader("dev", "true");//开发环境,bool类型
|
||||||
|
await ws.ConnectAsync(uri, CancellationToken.None); //建立连接
|
||||||
|
|
||||||
|
if (OnOpen != null)
|
||||||
|
OnOpen(ws, new EventArgs());
|
||||||
|
|
||||||
|
Send(@"{""protocol"":""json"", ""version"":1}");//建立之后第一步进行握手,使用json类型
|
||||||
|
|
||||||
|
//全部消息容器
|
||||||
|
List<byte> bs = new List<byte>();
|
||||||
|
//缓冲区
|
||||||
|
var buffer = new byte[1024 * 4];
|
||||||
|
//监听Socket信息
|
||||||
|
WebSocketReceiveResult result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||||
|
//是否关闭
|
||||||
|
while (!result.CloseStatus.HasValue)
|
||||||
|
{
|
||||||
|
//文本消息
|
||||||
|
if (result.MessageType == WebSocketMessageType.Text)
|
||||||
|
{
|
||||||
|
bs.AddRange(buffer.Take(result.Count));
|
||||||
|
|
||||||
|
//消息是否已接收完全
|
||||||
|
if (result.EndOfMessage)
|
||||||
|
{
|
||||||
|
var arr = RemoveSeparator(bs.ToArray());//过滤掉记录分隔符
|
||||||
|
|
||||||
|
//发送过来的消息
|
||||||
|
string userMsg = Encoding.UTF8.GetString(arr, 0, arr.Length);
|
||||||
|
|
||||||
|
if (OnMessage != null)
|
||||||
|
OnMessage(ws, userMsg);
|
||||||
|
|
||||||
|
//清空消息容器
|
||||||
|
bs = new List<byte>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//继续监听Socket信息
|
||||||
|
result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||||
|
}
|
||||||
|
////关闭WebSocket(服务端发起)
|
||||||
|
//await ws.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
netErr = "发生错误" + ex.Message;
|
||||||
|
|
||||||
|
if (OnError != null)
|
||||||
|
OnError(ws, ex);
|
||||||
|
|
||||||
|
//if (ws != null && ws.State == WebSocketState.Open)
|
||||||
|
// //关闭WebSocket(客户端发起)
|
||||||
|
// await ws.CloseAsync(WebSocketCloseStatus.Empty, ex.Message, CancellationToken.None);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (!isUserClose)
|
||||||
|
Close(ws.CloseStatus.Value, ws.CloseStatusDescription + netErr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 增加记录分隔符
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static byte[] AddSeparator(byte[] data)
|
||||||
|
{
|
||||||
|
List<byte> t = new List<byte>(data) { 0x1e };//0x1e record separator
|
||||||
|
return t.ToArray();
|
||||||
|
}
|
||||||
|
//删除记录分隔符
|
||||||
|
private static byte[] RemoveSeparator(byte[] data)
|
||||||
|
{
|
||||||
|
List<byte> t = new List<byte>(data);
|
||||||
|
t.Remove(0x1e);
|
||||||
|
return t.ToArray();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取时间戳
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private int GetTimestamp()
|
||||||
|
{
|
||||||
|
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));
|
||||||
|
int timestamp = Convert.ToInt32((DateTime.Now - dateTimeStart).TotalSeconds);
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 使用连接发送文本消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ws"></param>
|
||||||
|
/// <param name="mess"></param>
|
||||||
|
/// <returns>是否尝试了发送</returns>
|
||||||
|
public bool Send(string mess)
|
||||||
|
{
|
||||||
|
if (ws.State != WebSocketState.Open)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")},发送数据:{mess}");
|
||||||
|
var replyMess = Encoding.UTF8.GetBytes(mess);
|
||||||
|
//发送消息,结尾必须携带记录分隔符
|
||||||
|
await ws.SendAsync(new ArraySegment<byte>(AddSeparator(replyMess)), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用连接发送字节消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ws"></param>
|
||||||
|
/// <param name="mess"></param>
|
||||||
|
/// <returns>是否尝试了发送</returns>
|
||||||
|
public bool Send(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (ws.State != WebSocketState.Open)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
//发送消息
|
||||||
|
await ws.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Binary, true, CancellationToken.None);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭连接
|
||||||
|
/// </summary>
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
isUserClose = true;
|
||||||
|
Close(WebSocketCloseStatus.NormalClosure, "用户手动关闭");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close(WebSocketCloseStatus closeStatus, string statusDescription)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//关闭WebSocket(客户端发起)
|
||||||
|
await ws.CloseAsync(closeStatus, statusDescription, CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.Abort();
|
||||||
|
ws.Dispose();
|
||||||
|
|
||||||
|
if (OnClose != null)
|
||||||
|
OnClose(ws, new EventArgs());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MessagePack" Version="2.2.85" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
|
<PackageReference Include="System.Net.WebSockets.Client" Version="4.3.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Loading…
Reference in New Issue