Plane.Sdk3/PlaneGcsSdk.Contract.DtuClient_Shared/EhNetLoginMgr.cs

279 lines
12 KiB
C#
Raw Normal View History

2017-02-27 02:02:19 +08:00
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
}
}