chore: 提出 AppRouter 模块,以备后面共享使用
parent
991446940a
commit
fc4ff081f7
|
@ -7,36 +7,36 @@ using Newtonsoft.Json;
|
|||
namespace LeanCloud.Storage.Internal {
|
||||
public class AppRouterController {
|
||||
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)) {
|
||||
throw new ArgumentNullException(nameof(appId));
|
||||
}
|
||||
|
||||
try {
|
||||
locker.EnterUpgradeableReadLock();
|
||||
if (currentState != null && !currentState.IsExpired) {
|
||||
return currentState;
|
||||
}
|
||||
// 从 AppRouter 获取服务器地址,只触发,不等待
|
||||
QueryAsync(appId).ContinueWith(t => {
|
||||
if (t.IsFaulted) {
|
||||
if (currentState != null && !currentState.IsExpired) {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
} else {
|
||||
locker.EnterWriteLock();
|
||||
currentState = t.Result;
|
||||
currentState.Source = "router";
|
||||
locker.ExitWriteLock();
|
||||
await locker.WaitAsync();
|
||||
try {
|
||||
if (currentState == null) {
|
||||
try {
|
||||
currentState = await QueryAsync(appId);
|
||||
} catch (Exception) {
|
||||
currentState = AppRouterState.GetFallbackServers(appId);
|
||||
}
|
||||
});
|
||||
return AppRouterState.GetFallbackServers(appId);
|
||||
}
|
||||
return currentState;
|
||||
} finally {
|
||||
locker.ExitUpgradeableReadLock();
|
||||
locker.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<AppRouterState> QueryAsync(string appId) {
|
||||
Console.WriteLine("QueryAsync");
|
||||
|
||||
string url = string.Format("https://app-router.leancloud.cn/2/route?appId={0}", appId);
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
|
@ -52,13 +52,13 @@ namespace LeanCloud.Storage.Internal {
|
|||
string content = await response.Content.ReadAsStringAsync();
|
||||
response.Dispose();
|
||||
|
||||
return JsonConvert.DeserializeObject<AppRouterState>(content);
|
||||
AppRouterState state = JsonConvert.DeserializeObject<AppRouterState>(content);
|
||||
state.Source = "router";
|
||||
return state;
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
locker.EnterWriteLock();
|
||||
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>
|
||||
<ProjectReference Include="..\Storage\Storage.csproj" />
|
||||
<ProjectReference Include="..\..\AppRouter\AppRouter\AppRouter.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -15,6 +15,12 @@ namespace LeanCloud.Storage.Internal {
|
|||
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) {
|
||||
T obj = default;
|
||||
await Task.Run(() => {
|
||||
|
@ -22,5 +28,11 @@ namespace LeanCloud.Storage.Internal {
|
|||
});
|
||||
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.
|
||||
/// </summary>
|
||||
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>
|
||||
/// In the event that you would like to use the LeanCloud SDK
|
||||
/// from a completely portable project, with no platform-specific library required,
|
||||
|
@ -100,17 +63,6 @@ namespace LeanCloud {
|
|||
/// </summary>
|
||||
public string ApplicationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// LeanCloud C# SDK 支持的服务节点,目前支持华北,华东和北美公有云节点和私有节点,以及专属节点
|
||||
/// </summary>
|
||||
public AVRegion Region { get; set; }
|
||||
|
||||
internal int RegionValue {
|
||||
get {
|
||||
return (int)Region;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The LeanCloud application key for your app.
|
||||
/// </summary>
|
||||
|
@ -255,13 +207,6 @@ namespace LeanCloud {
|
|||
|
||||
internal static void Config(Configuration configuration) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -280,11 +225,10 @@ namespace LeanCloud {
|
|||
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 {
|
||||
ApplicationId = applicationId,
|
||||
ApplicationKey = applicationKey,
|
||||
Region = region
|
||||
ApplicationKey = applicationKey
|
||||
};
|
||||
Switch(configuration);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue