279 lines
12 KiB
C#
279 lines
12 KiB
C#
using System;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace PlaneGcsSdk.Contract.DtuClient
|
||
{
|
||
public partial class EhNetLoginMgr
|
||
{
|
||
#region Fields
|
||
private AutoResetEvent _loginEnNet;
|
||
private AutoResetEvent _sendRndCodeSignal;
|
||
private AutoResetEvent _sendBindCopterIDSignal;
|
||
private AutoResetEvent _sendUpdHandshakeSignal;
|
||
private AutoResetEvent _requestCopterListSignal;
|
||
private const string Protocol_SendRandCode = "J001"; //表示向服务器请求“发送随机码”的协议号
|
||
private const string Protocol_SendRandCode_Reply = "J002"; //表示服务端返回“请求发送随机码”的应答协议号
|
||
private const string Protocol_BindCopterID = "J003"; //表示向服务器请求“绑定飞机”的协议号
|
||
private const string Protocol_BindCopterID_Reply = "J004"; //表示服务端返回“请求绑定飞机”的应答协议号
|
||
private const string Protocol_RequestCopterList = "J007"; //表示向服务器请求“飞机列表”的请求协议号
|
||
private const string Protocol_ReceivedCopterItem = "J008"; //表示服务端返回“飞机列表中的一个飞机”的推送协议号
|
||
private const string Protocol_RecievedCopterInvailed = "J206";//表示由服务端通告“您所绑定的飞机已无效”的推送协议好
|
||
|
||
private string _errorCode; //请求过程由服务端返回的错误码的缓存变量
|
||
private string _errorCodeForRequestCopterList; //专为缓存“请求飞机列表”结果的错误号变量
|
||
private const string ErrorCode_Succeed = "0000"; //表示执行成功的错误码
|
||
private const string ErrorCode_EndCopterList = "0003"; //表示服务端返回“飞机列表完毕”的协议号
|
||
private CopterEntity _nextCopter; //当前请求的飞机实体
|
||
private string _usersname; //当前登录的账号
|
||
private const string DtuServerUsername = "10000"; // 在PLNet登陆体系里Dtu服务端的用户名
|
||
#endregion
|
||
|
||
#region Properties
|
||
/// <summary>
|
||
/// 在PLNet登陆体系里的用户别名
|
||
/// </summary>
|
||
public string NickName { get; protected set; }
|
||
|
||
/// <summary>
|
||
/// PLNet服务端的IP
|
||
/// </summary>
|
||
public string ServerIp { get; set; }
|
||
/// <summary>
|
||
/// PLNet服务端的监听端口
|
||
/// </summary>
|
||
public int ServerPort { get; set; }
|
||
/// <summary>
|
||
/// 表示当前所处的PLNet-Dtu连接状态(比如已登录PLNet,但没有建立Dtu透传管道)
|
||
/// </summary>
|
||
public ProcessStep ProcessSetp { get; protected set; }
|
||
/// <summary>
|
||
/// 登陆后获得的随机码
|
||
/// </summary>
|
||
public int RandCode { get; protected set; }
|
||
/// <summary>
|
||
/// 用于建立透传管道的Udp端口。
|
||
/// </summary>
|
||
public const int DTU_USER_PORT = 5250;
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 当前已绑定的飞机变为无效状态的事件
|
||
/// </summary>
|
||
public event EventHandler CopterLost;
|
||
|
||
public EhNetLoginMgr()
|
||
{
|
||
_loginEnNet = new AutoResetEvent(false);
|
||
_sendBindCopterIDSignal = new AutoResetEvent(false);
|
||
_sendRndCodeSignal = new AutoResetEvent(false);
|
||
_sendUpdHandshakeSignal = new AutoResetEvent(false);
|
||
_requestCopterListSignal = new AutoResetEvent(false);
|
||
|
||
InstanceEhNetObject();
|
||
_PLNet.CommandArrival += _ehNet_CommandArrival;
|
||
_PLNet.Disconnect += _ehNet_Disconnect;
|
||
_PLNet.DiscoveredOneUser += _ehNet_DiscoveredOneUser;
|
||
//_ehNet.ExceptionThrown += _ehNet_ExceptionThrown;
|
||
_PLNet.Login += _ehNet_Login;
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
_PLNet.CommandArrival -= _ehNet_CommandArrival;
|
||
_PLNet.Disconnect -= _ehNet_Disconnect;
|
||
_PLNet.DiscoveredOneUser -= _ehNet_DiscoveredOneUser;
|
||
//_ehNet.ExceptionThrown -= _ehNet_ExceptionThrown;
|
||
_PLNet.Login -= _ehNet_Login;
|
||
}
|
||
|
||
#region Public Methods
|
||
/// <summary>
|
||
/// 登陆到PLNet网络(第三个参数决定是否在登陆成功后发起获取飞机列表的请求)。
|
||
/// </summary>
|
||
/// <param name="username"></param>
|
||
/// <param name="pwd"></param>
|
||
/// <param name="gotCopterCallBack">获得得到的飞机事件</param>
|
||
public async Task Login(string username, string pwd, string ehNetServerIp,
|
||
Action<CopterEntity> gotCopterCallBack = null)
|
||
{
|
||
if (CheckIfLogined())
|
||
{
|
||
return;
|
||
}
|
||
_usersname = username;
|
||
await Task.Run(async () =>
|
||
{
|
||
await EhNetStart(ehNetServerIp, username, pwd);
|
||
if (!_loginEnNet.WaitOne(TimeSpan.FromSeconds(10)))
|
||
{
|
||
throw new Exception("登陆无响应失败!");
|
||
}
|
||
ProcessSetp = ProcessStep.EhNetLogin;
|
||
if (!string.IsNullOrEmpty(_PLNet.MyRND))
|
||
{
|
||
int value;
|
||
int.TryParse(_PLNet.MyRND, out value);
|
||
RandCode = value;
|
||
//发送随机码到Dtu服务端
|
||
await SendCommandToDtuServer($"{Protocol_SendRandCode};{username};{_PLNet.MyRND}");
|
||
if (!_sendRndCodeSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||
{
|
||
throw new Exception("发送随机码超时!");
|
||
}
|
||
else if (_errorCode != ErrorCode_Succeed)
|
||
{
|
||
throw new Exception("发送随机码失败:" + _errorCode);
|
||
}
|
||
ProcessSetp = ProcessStep.SendRandCode;
|
||
}
|
||
|
||
if (gotCopterCallBack != null)
|
||
{
|
||
int index = 0;
|
||
while (true)
|
||
{
|
||
await SendCommandToDtuServer($"{Protocol_RequestCopterList};{username};{index}");
|
||
if (_requestCopterListSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||
{
|
||
if (_errorCodeForRequestCopterList == ErrorCode_Succeed)
|
||
{
|
||
if (_nextCopter != null)
|
||
{
|
||
gotCopterCallBack.Invoke(_nextCopter);
|
||
}
|
||
//加1后继续请求
|
||
index++;
|
||
}
|
||
else if (_errorCodeForRequestCopterList == ErrorCode_EndCopterList)
|
||
{
|
||
//正常结束请求
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
throw new Exception($"请求获取飞机列表错误:{_errorCode}!");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
throw new Exception("请求获取飞机列表超时!");
|
||
}
|
||
}
|
||
}
|
||
}).ConfigureAwait(false);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 退出PLNet网络
|
||
/// </summary>
|
||
public void Logout()
|
||
{
|
||
_PLNet.Close();
|
||
ResetLoginStatus();
|
||
ProcessSetp = ProcessStep.None;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取飞机列表
|
||
/// </summary>
|
||
public async Task GetCopterList(Action<CopterEntity> gotCopterCallBack)
|
||
{
|
||
await Task.Run(async () =>
|
||
{
|
||
int index = 0;
|
||
while (true)
|
||
{
|
||
await SendCommandToDtuServer($"{Protocol_RequestCopterList};{_usersname};{index}");
|
||
if (_requestCopterListSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||
{
|
||
if (_errorCodeForRequestCopterList == ErrorCode_Succeed)
|
||
{
|
||
if (_nextCopter != null)
|
||
{
|
||
gotCopterCallBack.Invoke(_nextCopter);
|
||
}
|
||
//加1后继续请求
|
||
index++;
|
||
}
|
||
else if (_errorCodeForRequestCopterList == ErrorCode_EndCopterList)
|
||
{
|
||
//正常结束请求
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
//throw new Exception($"请求获取飞机列表错误:{_errorCode}!");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//throw new Exception("请求获取飞机列表超时!");
|
||
}
|
||
}
|
||
}).ConfigureAwait(false);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 申请绑定飞机
|
||
/// </summary>
|
||
public async Task AssignBindingCopter(string copterID)
|
||
{
|
||
//向Dtu服务端申请绑定飞机
|
||
await SendCommandToDtuServer($"{Protocol_BindCopterID};{_usersname};{copterID}");
|
||
if (!_sendBindCopterIDSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||
{
|
||
throw new Exception("申请绑定超时!");
|
||
}
|
||
else if (_errorCode != ErrorCode_Succeed)
|
||
{
|
||
throw new Exception("申请绑定失败:" + _errorCode);
|
||
}
|
||
ProcessSetp = ProcessStep.AssignCopter;
|
||
}
|
||
#endregion
|
||
|
||
#region Private Methods
|
||
private void AcceptProtocolCommand(string userIDFrom, string msg)
|
||
{
|
||
if (!string.IsNullOrEmpty(msg) && userIDFrom == DtuServerUsername)
|
||
{
|
||
var strList = msg.Split(';');
|
||
if (strList.Length >= 3)
|
||
{
|
||
switch (strList[0])
|
||
{
|
||
case Protocol_SendRandCode_Reply:
|
||
_errorCode = strList[2];
|
||
_sendRndCodeSignal.Set();
|
||
break;
|
||
|
||
case Protocol_BindCopterID_Reply:
|
||
_errorCode = strList[2];
|
||
_sendBindCopterIDSignal.Set();
|
||
break;
|
||
|
||
case Protocol_ReceivedCopterItem:
|
||
_errorCodeForRequestCopterList = strList[2];
|
||
if (strList.Length >= 5)
|
||
{
|
||
_nextCopter = new CopterEntity { ID = strList[3], Name = strList[4] };
|
||
}
|
||
else
|
||
{
|
||
_nextCopter = null;
|
||
}
|
||
_requestCopterListSignal.Set();
|
||
break;
|
||
|
||
case Protocol_RecievedCopterInvailed:
|
||
CopterLost?.Invoke(this, EventArgs.Empty);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
}
|