first commit
This commit is contained in:
178
Ultron.Proxy.Client/ServerConnnectionManager.cs
Normal file
178
Ultron.Proxy.Client/ServerConnnectionManager.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using Ultron.Proxy.Models;
|
||||
using Ultron.Proxy.Utils;
|
||||
|
||||
namespace Ultron.Proxy
|
||||
{
|
||||
public class ClientGroupEventArgs : EventArgs
|
||||
{
|
||||
public IEnumerable<TcpClient> NewClients;
|
||||
public ClientIdAppId App;
|
||||
}
|
||||
|
||||
public class ServerConnnectionManager
|
||||
{
|
||||
private int MAX_CONNECT_SIZE = 6;//magic value,单个应用最大连接数,有些应用端支持多连接,需要调高此值,当该值较大时,此值会增加
|
||||
private int ClientID = 0;
|
||||
private ServerConnnectionManager()
|
||||
{
|
||||
Router.Logger.Debug("ServerConnnectionManager initialized.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化配置,返回服务端返回的配置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<ClientModel> InitConfig()
|
||||
{
|
||||
ClientModel clientModel = await ReadConfigFromProvider();
|
||||
//要求服务端分配资源并获取服务端配置,待完善
|
||||
|
||||
this.ClientID = clientModel.ClientId;
|
||||
//分配appid给不同的Client
|
||||
ServiceClientListCollection = new Dictionary<int, ClientAppWorker>();
|
||||
for (int i = 0; i < clientModel.AppList.Count; i++)
|
||||
{
|
||||
var app = clientModel.AppList[i];
|
||||
ServiceClientListCollection.Add(clientModel.AppList[i].AppId, new ClientAppWorker()
|
||||
{
|
||||
AppId = app.AppId,
|
||||
Port = app.Port,
|
||||
TcpClientGroup = new List<TcpClient>(MAX_CONNECT_SIZE)
|
||||
});
|
||||
}
|
||||
return clientModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从服务端读取配置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<ClientModel> ReadConfigFromProvider()
|
||||
{
|
||||
//《c#并发编程经典实例》 9.3 超时后取消
|
||||
var config = Router.ClientConfig;
|
||||
Router.Logger.Debug("Reading Config From Provider..");
|
||||
TcpClient configClient = new TcpClient();
|
||||
var delayDispose = Task.Delay(TimeSpan.FromSeconds(600)).ContinueWith(_ => configClient.Dispose());
|
||||
var connectAsync = configClient.ConnectAsync(config.ProviderAddress, config.ProviderConfigPort);
|
||||
//超时则dispose掉
|
||||
var comletedTask = await Task.WhenAny(delayDispose, connectAsync);
|
||||
if (!connectAsync.IsCompleted)
|
||||
{
|
||||
throw new Exception("连接超时");
|
||||
}
|
||||
|
||||
var configStream = configClient.GetStream();
|
||||
|
||||
|
||||
//请求1 端口数
|
||||
var requestBytes = new ClientNewAppRequest
|
||||
{
|
||||
ClientId = 0,
|
||||
ClientCount = config.Clients.Count(obj => obj.AppID == 0) //appid为0的则是未分配的
|
||||
}.ToBytes();
|
||||
await configStream.WriteAsync(requestBytes, 0, requestBytes.Length);
|
||||
|
||||
//请求2 分配端口
|
||||
//var requestBytes
|
||||
byte[] requestBytes2 = new byte[config.Clients.Count * 2];
|
||||
int i = 0;
|
||||
foreach (var client in config.Clients)
|
||||
{
|
||||
byte[] portBytes = StringUtil.IntTo2Bytes(client.RemotePort);
|
||||
requestBytes2[2 * i] = portBytes[0];
|
||||
requestBytes2[2 * i + 1] = portBytes[1];
|
||||
i++;
|
||||
}
|
||||
await configStream.WriteAsync(requestBytes2, 0, requestBytes2.Length);
|
||||
|
||||
//读端口配置
|
||||
byte[] serverConfig = new byte[256];
|
||||
int readBytesCount = await configStream.ReadAsync(serverConfig, 0, serverConfig.Length);
|
||||
if (readBytesCount == 0) Router.Logger.Debug("服务器状态异常,已断开连接");
|
||||
return ClientModel.GetFromBytes(serverConfig, readBytesCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// clients Connected event.
|
||||
/// </summary>
|
||||
public event EventHandler ClientGroupConnected;
|
||||
|
||||
/// <summary>
|
||||
/// 将所有的app循环连接服务端
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task PollingToProvider()
|
||||
{
|
||||
var config = Router.ClientConfig;
|
||||
if (ClientID == 0) { Router.Logger.Debug("error:未连接客户端"); return; };
|
||||
//int hungryNumber = MAX_CONNECT_SIZE / 2;
|
||||
byte[] clientBytes = StringUtil.IntTo2Bytes(ClientID);
|
||||
|
||||
List<Task> taskList = new List<Task>();
|
||||
foreach (var kv in ServiceClientListCollection)
|
||||
{
|
||||
|
||||
int appid = kv.Key;
|
||||
await ConnectAppToServer(appid);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ConnectAppToServer(int appid)
|
||||
{
|
||||
var app = this.ServiceClientListCollection[appid];
|
||||
var config = Router.ClientConfig;
|
||||
// ClientAppWorker app = kv.Value;
|
||||
byte[] requestBytes = StringUtil.ClientIDAppIdToBytes(ClientID, appid);
|
||||
var clientList = new List<TcpClient>();
|
||||
//补齐
|
||||
TcpClient client = new TcpClient();
|
||||
await client.ConnectAsync(config.ProviderAddress, config.ProviderPort);
|
||||
//连完了马上发送端口信息过去,方便服务端分配
|
||||
await client.GetStream().WriteAsync(requestBytes, 0, requestBytes.Length);
|
||||
Router.Logger.Debug("ClientID:" + ClientID.ToString()
|
||||
+ " AppId:" + appid.ToString() + " 已连接");
|
||||
app.TcpClientGroup.Add(client);
|
||||
clientList.Add(client);
|
||||
//var clientList = new List<TcpClient>() { client };
|
||||
ClientGroupConnected(this, new ClientGroupEventArgs()
|
||||
{
|
||||
NewClients = clientList,
|
||||
App = new ClientIdAppId
|
||||
{
|
||||
ClientId = ClientID,
|
||||
AppId = appid
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//key:appid value;ClientApp
|
||||
public Dictionary<int, ClientAppWorker> ServiceClientListCollection;// = new Dictionary<int, List<TcpClient>>();
|
||||
//private static ServerConnnectionManager Instance = new Lazy<ServerConnnectionManager>(() => new ServerConnnectionManager()).Value;
|
||||
|
||||
|
||||
|
||||
public static ServerConnnectionManager Create()
|
||||
{
|
||||
return new ServerConnnectionManager();
|
||||
}
|
||||
|
||||
public TcpClient RemoveClient(int appId, TcpClient client)
|
||||
{
|
||||
if (ServiceClientListCollection[appId].TcpClientGroup.Remove(client))
|
||||
|
||||
return client;
|
||||
else
|
||||
{
|
||||
throw new Exception("无此client");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user