客户端获取硬件信息,单元测试通过
This commit is contained in:
parent
889765144a
commit
9178790639
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Stardust\Stardust.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using NewLife;
|
||||
using NewLife.Security;
|
||||
using Stardust;
|
||||
using Xunit;
|
||||
|
||||
namespace ClientTest
|
||||
{
|
||||
public class StarClientTests
|
||||
{
|
||||
public String Server { get; set; } = "http://localhost:6600";
|
||||
//public StarClient Client { get; }
|
||||
|
||||
public StarClientTests()
|
||||
{
|
||||
//Client = new StarClient(Server);
|
||||
//Client.Add("default", new Uri(Server));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetLoginInfoTest()
|
||||
{
|
||||
var client = new StarClient
|
||||
{
|
||||
Code = Rand.NextString(8),
|
||||
Secret = Rand.NextString(16)
|
||||
};
|
||||
|
||||
var inf = client.GetLoginInfo();
|
||||
Assert.NotNull(inf);
|
||||
Assert.NotNull(inf.Node);
|
||||
|
||||
Assert.Equal(client.Code, inf.Code);
|
||||
Assert.Equal(client.Secret.MD5(), inf.Secret);
|
||||
|
||||
var node = client.GetNodeInfo();
|
||||
var mi = MachineInfo.Current;
|
||||
Assert.Equal(mi.UUID, node.UUID);
|
||||
Assert.Equal(mi.Guid, node.MachineGuid);
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "登录测试")]
|
||||
[InlineData("abcd", "1234")]
|
||||
[InlineData(null, "1234")]
|
||||
[InlineData("abcd", null)]
|
||||
public async void LoginTest(String code, String secret)
|
||||
{
|
||||
var client = new StarClient(Server)
|
||||
{
|
||||
Code = code,
|
||||
Secret = secret
|
||||
};
|
||||
|
||||
var rs = await client.Login();
|
||||
Assert.NotNull(rs);
|
||||
Assert.NotNull(client.Info);
|
||||
Assert.True(client.Logined);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void LogoutTest()
|
||||
{
|
||||
var client = new StarClient(Server);
|
||||
|
||||
await client.Login();
|
||||
await client.Logout("test");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHeartInfoTest()
|
||||
{
|
||||
var client = new StarClient();
|
||||
var inf = client.GetHeartInfo();
|
||||
Assert.NotNull(inf);
|
||||
Assert.NotEmpty(inf.Macs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +1,23 @@
|
|||
using NewLife;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NewLife;
|
||||
using NewLife.Agent;
|
||||
using NewLife.Log;
|
||||
using NewLife.Net;
|
||||
using NewLife.Remoting;
|
||||
using NewLife.Threading;
|
||||
using Stardust;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace StarAgent
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(String[] args)
|
||||
{
|
||||
new MyService().Main();
|
||||
}
|
||||
static void Main(String[] args) => new MyService().Main();
|
||||
}
|
||||
|
||||
/// <summary>服务类。名字可以自定义</summary>
|
||||
class MyService : AgentServiceBase<MyService>
|
||||
{
|
||||
/// <summary>是否使用线程池调度。false表示禁用线程池,改用Agent线程</summary>
|
||||
public Boolean Pooling { get; set; } = true;
|
||||
|
||||
public MyService()
|
||||
{
|
||||
ServiceName = "StarAgent";
|
||||
|
@ -38,13 +32,13 @@ namespace StarAgent
|
|||
if (_Client == null)
|
||||
{
|
||||
var set = Setting.Current;
|
||||
if (!set.Server.IsNullOrEmpty())
|
||||
InitClient(set.Server);
|
||||
else
|
||||
{
|
||||
WriteLog("未配置服务端地址,开始自动发现");
|
||||
StartDiscover();
|
||||
}
|
||||
//if (!set.Server.IsNullOrEmpty())
|
||||
InitClient(set.Server);
|
||||
//else
|
||||
//{
|
||||
// WriteLog("未配置服务端地址,开始自动发现");
|
||||
// StartDiscover();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,14 +52,14 @@ namespace StarAgent
|
|||
|
||||
var client = new StarClient(server)
|
||||
{
|
||||
UserName = Environment.MachineName,
|
||||
Password = Environment.MachineName,
|
||||
Code = Environment.MachineName,
|
||||
Secret = Environment.MachineName,
|
||||
Log = XTrace.Log,
|
||||
};
|
||||
if (set.Debug) client.EncoderLog = XTrace.Log;
|
||||
//if (set.Debug) client.EncoderLog = XTrace.Log;
|
||||
|
||||
client.Open();
|
||||
client.LoginAsync();
|
||||
//client.Open();
|
||||
client.Login();
|
||||
|
||||
_Client = client;
|
||||
}
|
||||
|
@ -96,63 +90,63 @@ namespace StarAgent
|
|||
}
|
||||
|
||||
#region 自动发现服务端
|
||||
private ApiClient _udp;
|
||||
private TimerX _udp_timer;
|
||||
private void StartDiscover()
|
||||
{
|
||||
var tc = new ApiClient("udp://255.255.255.255:6666")
|
||||
{
|
||||
UsePool = false,
|
||||
Log = XTrace.Log,
|
||||
EncoderLog = XTrace.Log,
|
||||
Timeout = 1_000
|
||||
};
|
||||
//private ApiClient _udp;
|
||||
//private TimerX _udp_timer;
|
||||
//private void StartDiscover()
|
||||
//{
|
||||
// var tc = new ApiClient("udp://255.255.255.255:6666")
|
||||
// {
|
||||
// UsePool = false,
|
||||
// Log = XTrace.Log,
|
||||
// EncoderLog = XTrace.Log,
|
||||
// Timeout = 1_000
|
||||
// };
|
||||
|
||||
tc.Open();
|
||||
// tc.Open();
|
||||
|
||||
// 定时广播
|
||||
_udp_timer = new TimerX(OnDiscover, tc, 0, 5_000) { Async = true };
|
||||
// // 定时广播
|
||||
// _udp_timer = new TimerX(OnDiscover, tc, 0, 5_000) { Async = true };
|
||||
|
||||
_udp = tc;
|
||||
}
|
||||
// _udp = tc;
|
||||
//}
|
||||
|
||||
private void OnDiscover(Object state)
|
||||
{
|
||||
//var udp = new UdpServer();
|
||||
//udp.Log = XTrace.Log;
|
||||
//private void OnDiscover(Object state)
|
||||
//{
|
||||
// //var udp = new UdpServer();
|
||||
// //udp.Log = XTrace.Log;
|
||||
|
||||
//var ep = new IPEndPoint(IPAddress.Broadcast, 6666);
|
||||
//var session = udp.CreateSession(ep);
|
||||
//session.Send("Hello");
|
||||
// //var ep = new IPEndPoint(IPAddress.Broadcast, 6666);
|
||||
// //var session = udp.CreateSession(ep);
|
||||
// //session.Send("Hello");
|
||||
|
||||
var tc = state as ApiClient;
|
||||
// var tc = state as ApiClient;
|
||||
|
||||
var dic = tc.Invoke<IDictionary<String, Object>>("Discover", new { state = DateTime.Now.ToFullString() });
|
||||
if (dic == null || dic.Count == 0) return;
|
||||
// var dic = tc.Invoke<IDictionary<String, Object>>("Discover", new { state = DateTime.Now.ToFullString() });
|
||||
// if (dic == null || dic.Count == 0) return;
|
||||
|
||||
var str = dic["Server"] + "";
|
||||
if (str.IsNullOrEmpty()) return;
|
||||
// var str = dic["Server"] + "";
|
||||
// if (str.IsNullOrEmpty()) return;
|
||||
|
||||
//WriteLog("收到[{0}]:{1}", tc, str);
|
||||
// //WriteLog("收到[{0}]:{1}", tc, str);
|
||||
|
||||
if (!str.IsNullOrEmpty())
|
||||
{
|
||||
var uri = new NetUri(str);
|
||||
if (!uri.Host.IsNullOrEmpty() && uri.Port > 0)
|
||||
{
|
||||
WriteLog("发现服务器:{0}", uri);
|
||||
// if (!str.IsNullOrEmpty())
|
||||
// {
|
||||
// var uri = new NetUri(str);
|
||||
// if (!uri.Host.IsNullOrEmpty() && uri.Port > 0)
|
||||
// {
|
||||
// WriteLog("发现服务器:{0}", uri);
|
||||
|
||||
// 停止广播
|
||||
_udp_timer.TryDispose();
|
||||
_udp_timer = null;
|
||||
// // 停止广播
|
||||
// _udp_timer.TryDispose();
|
||||
// _udp_timer = null;
|
||||
|
||||
_udp.TryDispose();
|
||||
_udp = null;
|
||||
// _udp.TryDispose();
|
||||
// _udp = null;
|
||||
|
||||
InitClient(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
// InitClient(str);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
#endregion
|
||||
|
||||
/// <summary>数据测试,菜单t</summary>
|
||||
|
|
|
@ -51,8 +51,8 @@ namespace Stardust.Models
|
|||
/// <summary>MAC地址</summary>
|
||||
public String Macs { get; set; }
|
||||
|
||||
/// <summary>串口</summary>
|
||||
public String COMs { get; set; }
|
||||
///// <summary>串口</summary>
|
||||
//public String COMs { get; set; }
|
||||
|
||||
/// <summary>安装路径</summary>
|
||||
public String InstallPath { get; set; }
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using NewLife;
|
||||
using NewLife.Log;
|
||||
using NewLife.Net;
|
||||
using NewLife.Reflection;
|
||||
using NewLife.Remoting;
|
||||
using NewLife.Serialization;
|
||||
using NewLife.Threading;
|
||||
using Stardust.Models;
|
||||
using Stardust.Services;
|
||||
|
||||
namespace Stardust
|
||||
{
|
||||
|
@ -14,95 +19,292 @@ namespace Stardust
|
|||
public class StarClient : ApiHttpClient
|
||||
{
|
||||
#region 属性
|
||||
/// <summary>用户名</summary>
|
||||
public String UserName { get; set; }
|
||||
/// <summary>证书</summary>
|
||||
public String Code { get; set; }
|
||||
|
||||
/// <summary>密码</summary>
|
||||
public String Password { get; set; }
|
||||
/// <summary>密钥</summary>
|
||||
public String Secret { get; set; }
|
||||
|
||||
/// <summary>是否已登录</summary>
|
||||
public Boolean Logined { get; set; }
|
||||
|
||||
/// <summary>最后一次登录成功后的消息</summary>
|
||||
public IDictionary<String, Object> Info { get; private set; }
|
||||
public LoginResponse Info { get; private set; }
|
||||
|
||||
/// <summary>请求到服务端并返回的延迟时间。单位ms</summary>
|
||||
public Int32 Delay { get; set; }
|
||||
|
||||
/// <summary>命令队列</summary>
|
||||
public IQueueService<CommandModel> CommandQueue { get; } = new QueueService<CommandModel>();
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
#region 构造
|
||||
/// <summary>实例化</summary>
|
||||
public StarClient()
|
||||
{
|
||||
Log = XTrace.Log;
|
||||
|
||||
_task = MachineInfo.RegisterAsync();
|
||||
}
|
||||
|
||||
/// <summary>实例化</summary>
|
||||
/// <param name="uri"></param>
|
||||
public StarClient(String uri)
|
||||
/// <param name="urls"></param>
|
||||
public StarClient(String urls) : this()
|
||||
{
|
||||
//if (!uri.IsNullOrEmpty())
|
||||
//{
|
||||
// var u = new Uri(uri);
|
||||
|
||||
// Servers = new[] { "{2}://{0}:{1}".F(u.Host, u.Port, u.Scheme) };
|
||||
|
||||
// var us = u.UserInfo.Split(":");
|
||||
// if (us.Length > 0) UserName = us[0];
|
||||
// if (us.Length > 1) Password = us[1];
|
||||
//}
|
||||
if (!urls.IsNullOrEmpty())
|
||||
{
|
||||
var ss = urls.Split(",");
|
||||
for (var i = 0; i < ss.Length; i++)
|
||||
{
|
||||
Add("service" + (i + 1), new Uri(ss[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 登录
|
||||
///// <summary>连接后自动登录</summary>
|
||||
///// <param name="client">客户端</param>
|
||||
///// <param name="force">强制登录</param>
|
||||
//protected override async Task<Object> OnLoginAsync(ISocketClient client, Boolean force)
|
||||
//{
|
||||
// if (Logined && !force) return null;
|
||||
/// <summary>登录</summary>
|
||||
/// <returns></returns>
|
||||
public async Task<Object> Login()
|
||||
{
|
||||
XTrace.WriteLine("登录:{0}", Code);
|
||||
|
||||
// var asmx = AssemblyX.Entry;
|
||||
var info = GetLoginInfo();
|
||||
|
||||
// var arg = new
|
||||
// {
|
||||
// user = UserName,
|
||||
// pass = Password.MD5(),
|
||||
// machine = Environment.MachineName,
|
||||
// processid = Process.GetCurrentProcess().Id,
|
||||
// version = asmx?.Version,
|
||||
// compile = asmx?.Compile,
|
||||
// };
|
||||
Logined = false;
|
||||
|
||||
// var rs = await base.InvokeWithClientAsync<Object>(client, "Login", arg);
|
||||
// if (Setting.Current.Debug) XTrace.WriteLine("登录{0}成功!{1}", client, rs.ToJson());
|
||||
var rs = Info = await LoginAsync(info);
|
||||
if (rs != null && !rs.Code.IsNullOrEmpty())
|
||||
{
|
||||
XTrace.WriteLine("下发证书:{0}/{1}", rs.Code, rs.Secret);
|
||||
Code = rs.Code;
|
||||
Secret = rs.Secret;
|
||||
}
|
||||
|
||||
// Logined = true;
|
||||
// 登录后设置用于用户认证的token
|
||||
Token = rs.Token;
|
||||
|
||||
// return Info = rs as IDictionary<String, Object>;
|
||||
//}
|
||||
Logined = true;
|
||||
|
||||
if (Logined && _timer == null)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_timer == null)
|
||||
{
|
||||
_timer = new TimerX(s => Ping(), null, 5_000, 60_000, "Device") { Async = true };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Info;
|
||||
}
|
||||
|
||||
/// <summary>获取登录信息</summary>
|
||||
/// <returns></returns>
|
||||
public LoginInfo GetLoginInfo()
|
||||
{
|
||||
var di = GetNodeInfo();
|
||||
var ext = new LoginInfo
|
||||
{
|
||||
Code = Code,
|
||||
Secret = Secret.IsNullOrEmpty() ? null : Secret.MD5(),
|
||||
|
||||
Node = di,
|
||||
};
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
private readonly Task<MachineInfo> _task;
|
||||
/// <summary>获取设备信息</summary>
|
||||
/// <returns></returns>
|
||||
public NodeInfo GetNodeInfo()
|
||||
{
|
||||
var mi = MachineInfo.Current ?? _task.Result;
|
||||
|
||||
var asm = AssemblyX.Entry ?? AssemblyX.Create(Assembly.GetExecutingAssembly());
|
||||
//var ps = System.IO.Ports.SerialPort.GetPortNames();
|
||||
var mcs = NetHelper.GetMacs().Select(e => e.ToHex("-")).OrderBy(e => e).Join(",");
|
||||
var di = new NodeInfo
|
||||
{
|
||||
Version = asm.FileVersion,
|
||||
Compile = asm.Compile,
|
||||
|
||||
OSName = mi.OSName,
|
||||
OSVersion = mi.OSVersion,
|
||||
|
||||
MachineName = Environment.MachineName,
|
||||
UserName = Environment.UserName,
|
||||
|
||||
ProcessorCount = Environment.ProcessorCount,
|
||||
Memory = mi.Memory,
|
||||
AvailableMemory = mi.AvailableMemory,
|
||||
Processor = mi.Processor,
|
||||
CpuID = mi.CpuID,
|
||||
CpuRate = mi.CpuRate,
|
||||
UUID = mi.UUID,
|
||||
MachineGuid = mi.Guid,
|
||||
|
||||
Macs = mcs,
|
||||
//COMs = ps.Join(","),
|
||||
|
||||
InstallPath = ".".GetFullPath(),
|
||||
Runtime = Environment.Version + "",
|
||||
|
||||
Time = DateTime.Now,
|
||||
};
|
||||
|
||||
return di;
|
||||
}
|
||||
|
||||
/// <summary>注销</summary>
|
||||
/// <param name="reason"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Object> Logout(String reason)
|
||||
{
|
||||
if (!Logined) return null;
|
||||
|
||||
XTrace.WriteLine("注销:{0} {1}", Code, reason);
|
||||
|
||||
try
|
||||
{
|
||||
var rs = await LogoutAsync(reason);
|
||||
if (rs != null)
|
||||
{
|
||||
// 更新令牌
|
||||
Token = rs.Token;
|
||||
}
|
||||
|
||||
Logined = false;
|
||||
|
||||
return rs;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XTrace.WriteException(ex);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>登录</summary>
|
||||
/// <param name="inf">登录信息</param>
|
||||
/// <returns></returns>
|
||||
private async Task<LoginResponse> LoginAsync(LoginInfo inf) => await PostAsync<LoginResponse>("Node/Login", inf);
|
||||
|
||||
/// <summary>注销</summary>
|
||||
/// <returns></returns>
|
||||
private async Task<LoginResponse> LogoutAsync(String reason) => await GetAsync<LoginResponse>("Node/Logout", new { reason });
|
||||
#endregion
|
||||
|
||||
#region 心跳报告
|
||||
/// <summary>获取心跳信息</summary>
|
||||
public PingInfo GetHeartInfo()
|
||||
{
|
||||
var asm = AssemblyX.Entry;
|
||||
//var ps = System.IO.Ports.SerialPort.GetPortNames();
|
||||
var pcs = new List<Process>();
|
||||
foreach (var item in Process.GetProcesses().OrderBy(e => e.SessionId).ThenBy(e => e.ProcessName))
|
||||
{
|
||||
var name = item.ProcessName;
|
||||
if (name.EqualIgnoreCase("svchost", "dllhost", "conhost")) continue;
|
||||
|
||||
if (!pcs.Contains(item)) pcs.Add(item);
|
||||
}
|
||||
|
||||
var mi = MachineInfo.Current;
|
||||
mi.Refresh();
|
||||
|
||||
var mcs = NetHelper.GetMacs().Select(e => e.ToHex("-")).OrderBy(e => e).Join(",");
|
||||
var ext = new PingInfo
|
||||
{
|
||||
AvailableMemory = mi.AvailableMemory,
|
||||
CpuRate = mi.CpuRate,
|
||||
|
||||
Macs = mcs,
|
||||
//COMs = ps.Join(","),
|
||||
|
||||
Processes = pcs.Join(",", e => e.ProcessName),
|
||||
|
||||
Time = DateTime.Now.ToLong(),
|
||||
Delay = Delay,
|
||||
};
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
private TimerX _timer;
|
||||
/// <summary>心跳</summary>
|
||||
/// <returns></returns>
|
||||
public async Task<Object> Ping()
|
||||
{
|
||||
XTrace.WriteLine("心跳");
|
||||
|
||||
var inf = GetHeartInfo();
|
||||
|
||||
try
|
||||
{
|
||||
var rs = await PingAsync(inf);
|
||||
if (rs != null)
|
||||
{
|
||||
var dt = rs.Time.ToDateTime();
|
||||
if (dt.Year > 2000)
|
||||
{
|
||||
// 计算延迟
|
||||
var ts = DateTime.Now - dt;
|
||||
var ms = (Int32)ts.TotalMilliseconds;
|
||||
if (Delay > 0)
|
||||
Delay = (Delay + ms) / 2;
|
||||
else
|
||||
Delay = ms;
|
||||
}
|
||||
|
||||
// 推队列
|
||||
if (rs.Commands != null && rs.Commands.Length > 0)
|
||||
{
|
||||
foreach (var item in rs.Commands)
|
||||
{
|
||||
CommandQueue.Public(item.Command, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is AggregateException agg)
|
||||
{
|
||||
if (agg.InnerExceptions[0] is ApiException aex && aex.Code == 402)
|
||||
{
|
||||
XTrace.WriteLine("重新登录");
|
||||
return Login();
|
||||
}
|
||||
}
|
||||
|
||||
XTrace.WriteLine("心跳异常 {0}", (String)ex.GetTrue().Message);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>心跳</summary>
|
||||
/// <param name="inf"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<PingResponse> PingAsync(PingInfo inf) => await PostAsync<PingResponse>("Node/Ping", inf);
|
||||
|
||||
/// <summary>上报命令结果,如截屏、抓日志</summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<Object> ReportAsync(Int32 id, Byte[] data) => await PostAsync<Object>("Device/Report?Id=" + id, data);
|
||||
#endregion
|
||||
|
||||
#region 核心方法
|
||||
///// <summary>上报服务</summary>
|
||||
///// <param name="nameSpace"></param>
|
||||
///// <param name="services"></param>
|
||||
///// <returns></returns>
|
||||
//public async Task<Boolean> ReportAsync(String nameSpace, String[] services)
|
||||
//{
|
||||
// return await InvokeAsync<Boolean>("Report", new { nameSpace, services });
|
||||
//}
|
||||
#endregion
|
||||
|
||||
#region 辅助
|
||||
//#if DEBUG
|
||||
// /// <summary>创建</summary>
|
||||
// /// <param name="svr"></param>
|
||||
// /// <returns></returns>
|
||||
// protected override ISocketClient OnCreate(String svr)
|
||||
// {
|
||||
// var client = base.OnCreate(svr);
|
||||
// if (client != null) client.Log = Log;
|
||||
|
||||
// return client;
|
||||
// }
|
||||
//#endif
|
||||
#endregion
|
||||
#region 更新
|
||||
/// <summary>更新</summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<UpgradeInfo> UpgradeAsync(String channel) => await GetAsync<UpgradeInfo>("Node/Upgrade", new { channel });
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -26,8 +26,8 @@ namespace Test
|
|||
|
||||
var star = new StarClient("tcp://127.0.0.1:6666")
|
||||
{
|
||||
UserName = "test",
|
||||
Password = "pass"
|
||||
Code = "test",
|
||||
Secret = "pass"
|
||||
};
|
||||
|
||||
sc.Star = star;
|
||||
|
|
6
星尘.sln
6
星尘.sln
|
@ -27,6 +27,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
.editorconfig = .editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientTest", "ClientTest\ClientTest.csproj", "{7DE10A4D-1749-4474-A6B2-F52CA8462813}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -61,6 +63,10 @@ Global
|
|||
{0FF65D90-214F-405E-9674-6C0992BC61FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0FF65D90-214F-405E-9674-6C0992BC61FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0FF65D90-214F-405E-9674-6C0992BC61FD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7DE10A4D-1749-4474-A6B2-F52CA8462813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7DE10A4D-1749-4474-A6B2-F52CA8462813}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7DE10A4D-1749-4474-A6B2-F52CA8462813}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7DE10A4D-1749-4474-A6B2-F52CA8462813}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue