chore: 提出 AppRouter 模块,以备后面共享使用
parent
991446940a
commit
fc4ff081f7
|
|
@ -7,36 +7,36 @@ using Newtonsoft.Json;
|
||||||
namespace LeanCloud.Storage.Internal {
|
namespace LeanCloud.Storage.Internal {
|
||||||
public class AppRouterController {
|
public class AppRouterController {
|
||||||
private AppRouterState currentState;
|
private AppRouterState currentState;
|
||||||
private readonly ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
|
|
||||||
|
|
||||||
public AppRouterState Get(string appId) {
|
private readonly SemaphoreSlim locker = new SemaphoreSlim(1);
|
||||||
|
|
||||||
|
public async Task<AppRouterState> Get(string appId) {
|
||||||
if (string.IsNullOrEmpty(appId)) {
|
if (string.IsNullOrEmpty(appId)) {
|
||||||
throw new ArgumentNullException(nameof(appId));
|
throw new ArgumentNullException(nameof(appId));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
locker.EnterUpgradeableReadLock();
|
|
||||||
if (currentState != null && !currentState.IsExpired) {
|
if (currentState != null && !currentState.IsExpired) {
|
||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
// 从 AppRouter 获取服务器地址,只触发,不等待
|
|
||||||
QueryAsync(appId).ContinueWith(t => {
|
|
||||||
if (t.IsFaulted) {
|
|
||||||
|
|
||||||
} else {
|
await locker.WaitAsync();
|
||||||
locker.EnterWriteLock();
|
try {
|
||||||
currentState = t.Result;
|
if (currentState == null) {
|
||||||
currentState.Source = "router";
|
try {
|
||||||
locker.ExitWriteLock();
|
currentState = await QueryAsync(appId);
|
||||||
|
} catch (Exception) {
|
||||||
|
currentState = AppRouterState.GetFallbackServers(appId);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return AppRouterState.GetFallbackServers(appId);
|
return currentState;
|
||||||
} finally {
|
} finally {
|
||||||
locker.ExitUpgradeableReadLock();
|
locker.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AppRouterState> QueryAsync(string appId) {
|
public async Task<AppRouterState> QueryAsync(string appId) {
|
||||||
|
Console.WriteLine("QueryAsync");
|
||||||
|
|
||||||
string url = string.Format("https://app-router.leancloud.cn/2/route?appId={0}", appId);
|
string url = string.Format("https://app-router.leancloud.cn/2/route?appId={0}", appId);
|
||||||
|
|
||||||
HttpClient client = new HttpClient();
|
HttpClient client = new HttpClient();
|
||||||
|
|
@ -52,13 +52,13 @@ namespace LeanCloud.Storage.Internal {
|
||||||
string content = await response.Content.ReadAsStringAsync();
|
string content = await response.Content.ReadAsStringAsync();
|
||||||
response.Dispose();
|
response.Dispose();
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject<AppRouterState>(content);
|
AppRouterState state = JsonConvert.DeserializeObject<AppRouterState>(content);
|
||||||
|
state.Source = "router";
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear() {
|
public void Clear() {
|
||||||
locker.EnterWriteLock();
|
|
||||||
currentState = null;
|
currentState = null;
|
||||||
locker.ExitWriteLock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LeanCloud.Storage.Internal;
|
||||||
|
|
||||||
|
namespace LeanCloudTests {
|
||||||
|
public class AppRouterTest {
|
||||||
|
[Test]
|
||||||
|
public async Task GetServers() {
|
||||||
|
var appRouter = new AppRouterController();
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
var state = await appRouter.Get("BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz");
|
||||||
|
TestContext.Out.WriteLine(state.ApiServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,5 +16,6 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Storage\Storage.csproj" />
|
<ProjectReference Include="..\Storage\Storage.csproj" />
|
||||||
|
<ProjectReference Include="..\..\AppRouter\AppRouter\AppRouter.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,12 @@ namespace LeanCloud.Storage.Internal {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Task<string> SerializeAsync(object obj) {
|
||||||
|
return Task.Run(() => {
|
||||||
|
return JsonConvert.SerializeObject(obj);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<T> DeserializeObjectAsync<T>(string str, params JsonConverter[] converters) {
|
public static async Task<T> DeserializeObjectAsync<T>(string str, params JsonConverter[] converters) {
|
||||||
T obj = default;
|
T obj = default;
|
||||||
await Task.Run(() => {
|
await Task.Run(() => {
|
||||||
|
|
@ -22,5 +28,11 @@ namespace LeanCloud.Storage.Internal {
|
||||||
});
|
});
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Task<T> DeserializeAsync<T>(string str, params JsonConverter[] converts) {
|
||||||
|
return Task.Run(() => {
|
||||||
|
return JsonConvert.DeserializeObject<T>(str, converts);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,43 +30,6 @@ namespace LeanCloud {
|
||||||
/// Represents the configuration of the LeanCloud SDK.
|
/// Represents the configuration of the LeanCloud SDK.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct Configuration {
|
public struct Configuration {
|
||||||
/// <summary>
|
|
||||||
/// 与 SDK 通讯的云端节点
|
|
||||||
/// </summary>
|
|
||||||
public enum AVRegion {
|
|
||||||
/// <summary>
|
|
||||||
/// 默认值,LeanCloud 华北节点,同 Public_North_China
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("please use Configuration.AVRegion.Public_North_China")]
|
|
||||||
Public_CN = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 默认值,华北公有云节点,同 Public_CN
|
|
||||||
/// </summary>
|
|
||||||
Public_North_China = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// LeanCloud 北美区公有云节点,同 Public_North_America
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("please use Configuration.AVRegion.Public_North_America")]
|
|
||||||
Public_US = 1,
|
|
||||||
/// <summary>
|
|
||||||
/// LeanCloud 北美区公有云节点,同 Public_US
|
|
||||||
/// </summary>
|
|
||||||
Public_North_America = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 华东公有云节点,同 Public_East_China
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("please use Configuration.AVRegion.Public_East_China")]
|
|
||||||
Vendor_Tencent = 2,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 华东公有云节点,同 Vendor_Tencent
|
|
||||||
/// </summary>
|
|
||||||
Public_East_China = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// In the event that you would like to use the LeanCloud SDK
|
/// In the event that you would like to use the LeanCloud SDK
|
||||||
/// from a completely portable project, with no platform-specific library required,
|
/// from a completely portable project, with no platform-specific library required,
|
||||||
|
|
@ -100,17 +63,6 @@ namespace LeanCloud {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ApplicationId { get; set; }
|
public string ApplicationId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// LeanCloud C# SDK 支持的服务节点,目前支持华北,华东和北美公有云节点和私有节点,以及专属节点
|
|
||||||
/// </summary>
|
|
||||||
public AVRegion Region { get; set; }
|
|
||||||
|
|
||||||
internal int RegionValue {
|
|
||||||
get {
|
|
||||||
return (int)Region;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The LeanCloud application key for your app.
|
/// The LeanCloud application key for your app.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -255,13 +207,6 @@ namespace LeanCloud {
|
||||||
|
|
||||||
internal static void Config(Configuration configuration) {
|
internal static void Config(Configuration configuration) {
|
||||||
lock (mutex) {
|
lock (mutex) {
|
||||||
var nodeHash = configuration.ApplicationId.Split('-');
|
|
||||||
if (nodeHash.Length > 1) {
|
|
||||||
if (nodeHash[1].Trim() == "9Nh9j0Va") {
|
|
||||||
configuration.Region = Configuration.AVRegion.Public_East_China;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentConfiguration = configuration;
|
CurrentConfiguration = configuration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -280,11 +225,10 @@ namespace LeanCloud {
|
||||||
Initialize(configuration);
|
Initialize(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Switch(string applicationId, string applicationKey, Configuration.AVRegion region = Configuration.AVRegion.Public_North_China) {
|
public static void Switch(string applicationId, string applicationKey) {
|
||||||
var configuration = new Configuration {
|
var configuration = new Configuration {
|
||||||
ApplicationId = applicationId,
|
ApplicationId = applicationId,
|
||||||
ApplicationKey = applicationKey,
|
ApplicationKey = applicationKey
|
||||||
Region = region
|
|
||||||
};
|
};
|
||||||
Switch(configuration);
|
Switch(configuration);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue