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 /// /// 在PLNet登陆体系里的用户别名 /// public string NickName { get; protected set; } /// /// PLNet服务端的IP /// public string ServerIp { get; set; } /// /// PLNet服务端的监听端口 /// public int ServerPort { get; set; } /// /// 表示当前所处的PLNet-Dtu连接状态(比如已登录PLNet,但没有建立Dtu透传管道) /// public ProcessStep ProcessSetp { get; protected set; } /// /// 登陆后获得的随机码 /// public int RandCode { get; protected set; } /// /// 用于建立透传管道的Udp端口。 /// public const int DTU_USER_PORT = 5250; #endregion /// /// 当前已绑定的飞机变为无效状态的事件 /// 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 /// /// 登陆到PLNet网络(第三个参数决定是否在登陆成功后发起获取飞机列表的请求)。 /// /// /// /// 获得得到的飞机事件 public async Task Login(string username, string pwd, string ehNetServerIp, Action 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); } /// /// 退出PLNet网络 /// public void Logout() { _PLNet.Close(); ResetLoginStatus(); ProcessSetp = ProcessStep.None; } /// /// 获取飞机列表 /// public async Task GetCopterList(Action 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); } /// /// 申请绑定飞机 /// 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 } }