using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using Vinno.IUS.Common.Log;
namespace Vinno.vCloud.Common.FIS
{
public class vCloudTerminalBuilder
{
///
/// connect default server before get terminal connection faster address info from address info list
/// if get null ,can not connected to internet
///
///
public static ServerInfo GetFasterServer(string filePath = null)
{
try
{
string settingFilePath = AppDomain.CurrentDomain.BaseDirectory;
if (string.IsNullOrEmpty(settingFilePath))
{
if (!string.IsNullOrEmpty(filePath))
{
settingFilePath = filePath;
}
else
{
return null;
}
}
ServerInfo fasterServer = null;
var speedResults = new ConcurrentDictionary();
var serverFilePath = Path.Combine(settingFilePath, "FISServerSettings.conf");
DefaultServerSettings serverSettings = null;
if (File.Exists(serverFilePath))
{
var stringValue = File.ReadAllText(serverFilePath);
serverSettings = JsonConvert.DeserializeObject(stringValue);
}
if (serverSettings == null)
{
serverSettings = new DefaultServerSettings
{
Servers = new List
{
new ServerInfo { Host = "s01.flyinsono.com", Port = 9096 },
new ServerInfo { Host = "cloud.flyinsono.com", Port = 9096 },
new ServerInfo { Host = "cloud.xinglinghui.com", Port = 9096 },
},
MasterServer = new ServerInfo { Host = "s01.flyinsono.com", Port = 9096 }
};
}
Parallel.ForEach(serverSettings.Servers, serverInfo =>
{
var speed = GetConnectServerSpeed(serverInfo.Host);
if (speed != -1)
{
speedResults.TryAdd(serverInfo, speed);
}
});
if (speedResults.Count == 0)
{
fasterServer = serverSettings.MasterServer;
}
else
{
foreach (var result in speedResults)
{
if (fasterServer == null)
{
fasterServer = result.Key;
}
else
{
if (fasterServer.Host == "cloud.xinglinghui.com" && speedResults[fasterServer] > result.Value + 5)
{
fasterServer = result.Key;
}
else if (result.Key.Host == "cloud.xinglinghui.com" && speedResults[fasterServer] > result.Value - 5)
{
fasterServer = result.Key;
}
else if (speedResults[fasterServer] > result.Value)
{
fasterServer = result.Key;
}
}
}
}
Logger.WriteLineInfo($"Get faster server is {fasterServer.Host}:{fasterServer.Port}");
return fasterServer;
}
catch (Exception ex)
{
Logger.WriteLineError($"Get faster server error: {ex}");
}
return new ServerInfo { Host = "s01.flyinsono.com", Port = 9096 };
}
///
/// Connect to server
///
/// The connection Info
///
public IvCloudTerminal Connect(ConnectionInfo connectionInfo, bool isUseOldTerminalSdk = false, string uniqueId = "", string terminalId = "")
{
if (string.IsNullOrEmpty(connectionInfo?.Account?.Name) || string.IsNullOrEmpty(connectionInfo?.Account?.Password))
{
return null;
}
var terminal = new vCloudTerminal(connectionInfo, isUseOldTerminalSdk);
try
{
terminal.Connect(uniqueId, terminalId);
}
catch (Exception e)
{
Logger.WriteLineError($"Termnial Login ex:{e}");
}
return terminal;
}
///
/// Register Account
///
///
///
public bool Register(ConnectionInfo connectionInfo)
{
if (string.IsNullOrEmpty(connectionInfo?.Account?.Name) || string.IsNullOrEmpty(connectionInfo?.Account?.Password) || string.IsNullOrEmpty(connectionInfo?.Organization))
{
return false;
}
var terminal = new vCloudTerminal(connectionInfo);
try
{
var result = terminal.Register();
terminal.Dispose();
return result;
}
catch (Exception e)
{
Logger.WriteLineError($"Termnial Register error, ex:{e}");
}
return false;
}
///
/// test connet server speed
///
///
///
private static int GetConnectServerSpeed(string serverUrl)
{
try
{
using (var ping = new Ping())
{
var successTimes = 0;
var totalTime = 0;
for (var i = 0; i < 4; i++)//第一次为预热
{
try
{
var reply = ping.Send(serverUrl, 3000);
if (reply.Status == IPStatus.Success && i > 0)
{
Logger.WriteLineInfo($"Connect serverUrl:{serverUrl}, spend time:{reply.RoundtripTime}ms");
totalTime += (int)reply.RoundtripTime;
successTimes++;
}
}
catch (Exception ex)
{
Logger.WriteLineError($"Connect serverUrl:{serverUrl} error, Exception:{ex}");
continue;
}
}
if (successTimes == 0)
{
Logger.WriteLineInfo($"Connect serverUrl:{serverUrl} fail, the success times is 0");
return -1;
}
else
{
var averageValue = totalTime / successTimes;
Logger.WriteLineInfo($"Connect serverUrl:{serverUrl},successTimes:{successTimes},spend time averageValue:{averageValue}ms");
return averageValue;
}
}
}
catch (Exception e)
{
Logger.WriteLineError($"Connect Server:{serverUrl}, SpeedTest exception:{e}");
return -1;
}
}
///
/// test connet server speed
///
///
///
private static int Old_GetConnectServerSpeed(string serverUrl, bool isUseHttps = false)
{
try
{
//The following two lines are used to avoid HTTPS security authentication, otherwise httpclient cannot access the unsafe link
var httpClientHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true
};
using (var httpClient = new HttpClient(httpClientHandler))
{
var stopWatch = new Stopwatch();
httpClient.Timeout = TimeSpan.FromSeconds(3);
var prefix = "http://";
if (isUseHttps)
{
prefix = "https://";
}
var successTimes = 0;
var totalTime = 0;
for (var i = 0; i < 4; i++)//第一次为预热
{
if (i > 0)
{
////TODO(FISJuly): removed?
Thread.Sleep(1000);
}
stopWatch.Restart();
try
{
var result = httpClient.GetAsync(prefix + serverUrl + "/HomePage/API/Connect.json").GetAwaiter().GetResult();
if (result != null)
{
var content = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
stopWatch.Stop();
if (result.IsSuccessStatusCode && content.Length > 0 && i > 0)
{
Logger.WriteLineInfo($"Connect serverUrl:{serverUrl}, spend time:{stopWatch.ElapsedMilliseconds}ms");
totalTime += (int)stopWatch.ElapsedMilliseconds;
successTimes++;
}
}
}
catch (Exception ex)
{
Logger.WriteLineError($"Connect serverUrl:{serverUrl} error, Exception:{ex}");
continue;
}
}
if (successTimes == 0)
{
Logger.WriteLineInfo($"Connect serverUrl:{serverUrl} fail, the success times is 0");
return -1;
}
else
{
var averageValue = totalTime / successTimes;
Logger.WriteLineInfo($"Connect serverUrl:{serverUrl},successTimes:{successTimes},spend time averageValue:{averageValue}ms");
return averageValue;
}
}
}
catch (Exception e)
{
Logger.WriteLineError($"Connect Server:{serverUrl}, SpeedTest exception:{e}");
return -1;
}
}
}
}