using JsonRpcLite.Network;
using JsonRpcLite.Rpc;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using Vinno.IUS.Common.Log;
using Vinno.vCloud.Common.FIS.Helper;
using WingInterfaceLibrary.DTO.ServerInfo;
using WingInterfaceLibrary.Interface;
using WingInterfaceLibrary.Request.FastestServer;
namespace Vinno.vCloud.Common.FIS
{
public class vCloudTerminalBuilderV2
{
///
/// 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, "FISServerSettingsV2.conf");
DefaultServerSettings serverSettings = null;
//serverSettings = GetFasterServerList(true);
if (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 = "bj.flyinsono.com", Port = 443 },
new ServerInfo { Host = "hk.flyinsono.com", Port = 443 },
new ServerInfo { Host = "fra.flyinsono.com", Port = 443 },
},
MasterServer = new ServerInfo { Host = "hk.flyinsono.com", Port = 443 }
};
}
}
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 (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 = "hk.flyinsono.com", Port = 443 };
}
private static DefaultServerSettings GetFasterServerList(bool isUseHttps = true)
{
try
{
string prefix;
if (isUseHttps)
{
prefix = "https://";
}
else
{
prefix = "http://";
}
using (var client = new JsonRpcClient())
{
var clientEngine = new JsonRpcHttpClientEngine($"{prefix}hk.flyinsono.com:443");
client.UseEngine(clientEngine);
var vinnoServerService = client.CreateProxy(6000);
var queryServerInfoRequest = new QueryServerInfoRequest();
List result = JsonRpcHelper.GetServerInfoList(vinnoServerService, queryServerInfoRequest);
if (result == null || result.Count == 0)
{
return null;
}
string host;
int port = 443;
var serverSetting = new DefaultServerSettings() { Servers = new List() };
foreach (var server in result)
{
var serverArray = server.Host.Split(':');
if (serverArray.Length == 1)
{
host = serverArray[0];
}
else if (serverArray.Length == 2)
{
host = serverArray[0];
int.TryParse(serverArray[1], out port);
}
else
{
throw new Exception($"Server Info Format is invalid:{server.Host}");
}
var serverInfo = new ServerInfo() { Host = host, Port = port };
if (serverSetting.MasterServer == null)
{
serverSetting.MasterServer = serverInfo;
}
serverSetting.Servers.Add(serverInfo);
}
return serverSetting;
}
}
catch (Exception ex)
{
Logger.WriteLineError($"vCloudTerminalBuilder2 GetFasterServerList Error:{ex}");
return null;
}
}
///
/// Connect to server
///
/// The connection Info
///
public IvCloudTerminalV2 Connect(ConnectionInfo connectionInfo, bool isUseHttps, bool isUseOldTerminalSdk, string uniqueId, string terminalId)
{
if (string.IsNullOrEmpty(connectionInfo?.Account?.Name) || string.IsNullOrEmpty(connectionInfo?.Account?.Password))
{
return null;
}
var terminalV2 = new vCloudTerminalV2(connectionInfo, isUseHttps, isUseOldTerminalSdk);
try
{
terminalV2.Connect(uniqueId, terminalId);
}
catch (Exception e)
{
Logger.WriteLineError($"Termnial Login ex:{e}");
}
return terminalV2;
}
///
/// Register Account
///
///
///
public bool Register(ConnectionInfo connectionInfo)
{
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;
}
}
/// 多个服务器会报错同时用Jsonrpc会报错
///
/// test connet server speed
///
///
///
private static int OldGetConnectServerSpeed(string serverUrl, bool isUseHttps = true)
{
try
{
var prefix = "http://";
if (isUseHttps)
{
prefix = "https://";
}
using (var client = new JsonRpcClient())
{
var clientEngine = new JsonRpcHttpClientEngine($"{prefix}{serverUrl}");
client.UseEngine(clientEngine);
var vinnoServerService = client.CreateProxy(5000);
var stopWatch = new Stopwatch();
var successTimes = 0;
var totalTime = 0;
for (var i = 0; i < 4; i++)//第一次为预热
{
if (i > 0)
{
Thread.Sleep(1000);
}
stopWatch.Restart();
try
{
var result = JsonRpcHelper.Echo(vinnoServerService);
stopWatch.Stop();
if (result != null && result.Code == 0 && i > 0)
{
Logger.WriteLineInfo($"Connect serverUrl:{serverUrl}, spend time:{stopWatch.ElapsedMilliseconds}ms");
totalTime += (int)stopWatch.ElapsedMilliseconds;
successTimes++;
}
}
catch (Exception ex)
{
stopWatch.Stop();
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;
}
}
}
}