177 lines
6.6 KiB
C#
177 lines
6.6 KiB
C#
|
using Plane;
|
|||
|
using Plane.Collections;
|
|||
|
using Plane.FormationCreator.Formation;
|
|||
|
using Plane.Logging;
|
|||
|
using GalaSoft.MvvmLight;
|
|||
|
using GalaSoft.MvvmLight.CommandWpf;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Collections.Concurrent;
|
|||
|
using System.Linq;
|
|||
|
using System.Net.Sockets;
|
|||
|
using System.Text;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using System.Windows;
|
|||
|
using System.Windows.Input;
|
|||
|
using Plane.Communication;
|
|||
|
using Plane.Copters;
|
|||
|
using Plane.Windows.Messages;
|
|||
|
using Plane.FormationCreator.Properties;
|
|||
|
using System.IO;
|
|||
|
|
|||
|
namespace Plane.FormationCreator.ViewModels
|
|||
|
{
|
|||
|
public class ConnectViewModel : ViewModelBase
|
|||
|
{
|
|||
|
public ConnectViewModel(CopterManager copterManager)
|
|||
|
{
|
|||
|
_copterManager = copterManager;
|
|||
|
}
|
|||
|
|
|||
|
private CopterManager _copterManager;
|
|||
|
|
|||
|
private const int PORT = 5250;
|
|||
|
|
|||
|
// 不严谨,稍微验证一下。
|
|||
|
private Regex _ipListRegex = new Regex(@"^(?:" + Environment.NewLine + @")*\d{1,3}(?:\.\d{1,3}){3}(?:" + Environment.NewLine + @"\d{1,3}(?:\.\d{1,3}){3})*(?:" + Environment.NewLine + @")*$", RegexOptions.Singleline | RegexOptions.Compiled);
|
|||
|
|
|||
|
// private string _IPs = @"192.168.1.11
|
|||
|
//192.168.1.12
|
|||
|
//192.168.1.13
|
|||
|
//192.168.1.14
|
|||
|
//192.168.1.15
|
|||
|
//192.168.1.16
|
|||
|
//192.168.1.17
|
|||
|
//192.168.1.18
|
|||
|
//192.168.1.19
|
|||
|
//192.168.1.20
|
|||
|
//";
|
|||
|
private string _IPs = Settings.Default.IPs;
|
|||
|
public string IPs
|
|||
|
{
|
|||
|
get { return _IPs; }
|
|||
|
set { Set(nameof(IPs), ref _IPs, value); }
|
|||
|
}
|
|||
|
|
|||
|
private bool _IsProcessing;
|
|||
|
public bool IsProcessing
|
|||
|
{
|
|||
|
get { return _IsProcessing; }
|
|||
|
set { Set(nameof(IsProcessing), ref _IsProcessing, value); }
|
|||
|
}
|
|||
|
|
|||
|
private ICommand _ConnectCommand;
|
|||
|
public ICommand ConnectCommand
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return _ConnectCommand ?? (_ConnectCommand = new RelayCommand<string>(async connectionType =>
|
|||
|
{
|
|||
|
if (!_ipListRegex.IsMatch(IPs))
|
|||
|
{
|
|||
|
Alert.Show($"您输入的 IP 格式不对!形如{Environment.NewLine}192.168.1.10{Environment.NewLine}192.168.1.11");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
IsProcessing = true;
|
|||
|
|
|||
|
var connectionStatusDict =
|
|||
|
IPs.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
|
|||
|
.Where(ip => _copterManager.Copters.All(c => c.Id != ip))
|
|||
|
.OrderBy(ip => ip)
|
|||
|
.Distinct()
|
|||
|
.ToDictionary(ip => ip, ip => (bool?)null);
|
|||
|
var timeIsOut = false;
|
|||
|
var uiThreadContext = SynchronizationContext.Current;
|
|||
|
new Action(async () =>
|
|||
|
{
|
|||
|
foreach (var ip in connectionStatusDict.Keys.ToList())
|
|||
|
{
|
|||
|
var Connection =
|
|||
|
connectionType == "SerialPort"
|
|||
|
? new SerialPortConnection("COM10") as IConnection
|
|||
|
: connectionType == "UDP"
|
|||
|
? new UdpConnection(ip, PORT) as IConnection
|
|||
|
: new TcpConnection(ip, PORT);
|
|||
|
var c = new Copter(Connection, uiThreadContext)
|
|||
|
//var c = new Copter(new SerialPortConnection("COM3"), uiThreadContext)
|
|||
|
{
|
|||
|
Id = ip,
|
|||
|
Name = ip.Substring(ip.LastIndexOf('.') + 1)
|
|||
|
};
|
|||
|
try
|
|||
|
{
|
|||
|
await c.ConnectAsync().ConfigureAwait(false);
|
|||
|
if (!timeIsOut)
|
|||
|
{
|
|||
|
connectionStatusDict[ip] = true;
|
|||
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
{
|
|||
|
_copterManager.Copters.Add(c);
|
|||
|
});
|
|||
|
//await c.GetCopterDataAsync();
|
|||
|
}
|
|||
|
}
|
|||
|
catch (SocketException)
|
|||
|
{
|
|||
|
connectionStatusDict[ip] = false;
|
|||
|
}
|
|||
|
catch (IOException)
|
|||
|
{ // A device attached to the system is not functioning.
|
|||
|
connectionStatusDict[ip] = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}).Invoke();
|
|||
|
for (int waitedTime = 0, timeStep = 500; waitedTime < 2000; waitedTime += timeStep)
|
|||
|
{
|
|||
|
await Task.Delay(timeStep).ConfigureAwait(false);
|
|||
|
if (connectionStatusDict.All(item => item.Value == true))
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
timeIsOut = true;
|
|||
|
IsProcessing = false;
|
|||
|
var ipsCanNotConnect = string.Join(Environment.NewLine, connectionStatusDict.Where(item => !(item.Value ?? false)).Select(item => item.Key));
|
|||
|
if (!string.IsNullOrEmpty(ipsCanNotConnect))
|
|||
|
{
|
|||
|
var message = $"无法连接以下 IP{Environment.NewLine}{ipsCanNotConnect}";
|
|||
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
{
|
|||
|
Alert.Show(message);
|
|||
|
});
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
CloseWindow();
|
|||
|
}
|
|||
|
}));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private Action _closeWindowCallback;
|
|||
|
public void SetCloseWindowAction(Action closeWindowAction)
|
|||
|
{
|
|||
|
_closeWindowCallback = closeWindowAction;
|
|||
|
}
|
|||
|
private void CloseWindow()
|
|||
|
{
|
|||
|
if (_closeWindowCallback == null) return;
|
|||
|
var dispatcher = App.Current.Dispatcher;
|
|||
|
if (dispatcher.CheckAccess())
|
|||
|
{
|
|||
|
_closeWindowCallback();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dispatcher.InvokeAsync(() =>
|
|||
|
{
|
|||
|
_closeWindowCallback.Invoke();
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|