Plane.Sdk3/PlaneGcsSdk.Contract.DtuClient_Shared/EhNetLoginMgr.cs
2017-02-27 02:02:19 +08:00

279 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}