com.taptap.sdk.core 4.3.12 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Mobile/Editor/NativeDependencies.xml +2 -2
- package/Resources/TapMessage.prefab +352 -0
- package/Resources/TapMessage.prefab.meta +10 -0
- package/Resources/TapSDKUIRoot.prefab +1 -1
- package/Resources/tap_toast_background.png +0 -0
- package/Resources/tap_toast_background.png.meta +128 -0
- package/Resources/tap_toast_background1.png +0 -0
- package/Resources/tap_toast_background1.png.meta +128 -0
- package/Runtime/Internal/Log/TapLog.cs +1 -1
- package/Runtime/Internal/Platform/PlatformTypeUtils.cs +5 -5
- package/Runtime/Internal/Utils/TapMessage.cs +69 -0
- package/Runtime/Internal/Utils/TapMessage.cs.meta +13 -0
- package/Runtime/Public/TapTapSDK.cs +1 -1
- package/Standalone/Runtime/Internal/Bean/TapGatekeeper.cs +42 -0
- package/Standalone/Runtime/Internal/{Http/TimeUtil.cs.meta → Bean/TapGatekeeper.cs.meta} +1 -1
- package/Standalone/Runtime/Internal/Bean.meta +8 -0
- package/Standalone/Runtime/Internal/Constants.cs +2 -2
- package/Standalone/Runtime/Internal/EventSender.cs +30 -19
- package/Standalone/Runtime/Internal/Http/TapHttp.cs +377 -0
- package/Standalone/Runtime/Internal/Http/{HttpClient.cs.meta → TapHttp.cs.meta} +1 -1
- package/Standalone/Runtime/Internal/Http/TapHttpBuilder.cs +92 -0
- package/Standalone/Runtime/Internal/Http/{NetUtils.cs.meta → TapHttpBuilder.cs.meta} +1 -1
- package/Standalone/Runtime/Internal/Http/TapHttpErrorConstants.cs +114 -0
- package/Standalone/Runtime/Internal/Http/TapHttpErrorConstants.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/TapHttpException.cs +71 -0
- package/Standalone/Runtime/Internal/Http/TapHttpException.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/TapHttpParser.cs +132 -0
- package/Standalone/Runtime/Internal/Http/TapHttpParser.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/TapHttpResponse.cs +37 -0
- package/Standalone/Runtime/Internal/Http/TapHttpResponse.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/TapHttpResult.cs +90 -0
- package/Standalone/Runtime/Internal/Http/TapHttpResult.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/TapHttpRetryStrategy.cs +237 -0
- package/Standalone/Runtime/Internal/Http/TapHttpRetryStrategy.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/TapHttpSign.cs +137 -0
- package/Standalone/Runtime/Internal/Http/TapHttpSign.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/TapHttpUtils.cs +166 -0
- package/Standalone/Runtime/Internal/Http/TapHttpUtils.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogHttpClient.cs +6 -17
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBase.cs +1 -1
- package/Standalone/Runtime/Internal/service/ITapLoginService.cs +9 -0
- package/Standalone/Runtime/Internal/service/ITapLoginService.cs.meta +11 -0
- package/Standalone/Runtime/Internal/service.meta +8 -0
- package/Standalone/Runtime/Public/TapCoreStandalone.cs +67 -81
- package/link.xml +4 -0
- package/link.xml.meta +7 -0
- package/package.json +1 -1
- package/Standalone/Runtime/Internal/Http/HttpClient.cs +0 -211
- package/Standalone/Runtime/Internal/Http/NetUtils.cs +0 -48
- package/Standalone/Runtime/Internal/Http/TimeUtil.cs +0 -30
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine;
|
|
3
|
+
using UnityEngine.UI;
|
|
4
|
+
public class TapMessage : MonoBehaviour {
|
|
5
|
+
|
|
6
|
+
public enum Time
|
|
7
|
+
{
|
|
8
|
+
threeSecond,
|
|
9
|
+
twoSecond,
|
|
10
|
+
oneSecond
|
|
11
|
+
};
|
|
12
|
+
public enum Position
|
|
13
|
+
{
|
|
14
|
+
top,
|
|
15
|
+
bottom
|
|
16
|
+
};
|
|
17
|
+
public static void ShowMessage ( string msg, TapMessage.Position position, TapMessage.Time time )
|
|
18
|
+
{
|
|
19
|
+
|
|
20
|
+
//Load message prefab from resources folder
|
|
21
|
+
GameObject messagePrefab = Resources.Load ( "TapMessage" ) as GameObject;
|
|
22
|
+
//Get container object of message
|
|
23
|
+
GameObject containerObject = messagePrefab.gameObject.transform.GetChild ( 0 ).gameObject;
|
|
24
|
+
//Get text object
|
|
25
|
+
GameObject textObject = containerObject.gameObject.transform.GetChild ( 0 ).GetChild ( 0 ).gameObject;
|
|
26
|
+
//Get text property
|
|
27
|
+
Text msg_text = textObject.GetComponent<Text> ( );
|
|
28
|
+
//Set message to text ui
|
|
29
|
+
msg_text.text = msg;
|
|
30
|
+
//Set position of container object of message
|
|
31
|
+
SetPosition ( containerObject.GetComponent<RectTransform> ( ), position );
|
|
32
|
+
//Spawn message object with all changes
|
|
33
|
+
GameObject clone = Instantiate ( messagePrefab );
|
|
34
|
+
// Destroy clone of message object according to the time
|
|
35
|
+
RemoveClone ( clone, time );
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private static void SetPosition ( RectTransform rectTransform, Position position )
|
|
39
|
+
{
|
|
40
|
+
if (position == Position.top)
|
|
41
|
+
{
|
|
42
|
+
rectTransform.anchorMin = new Vector2 ( 0.5f, 1f );
|
|
43
|
+
rectTransform.anchorMax = new Vector2 ( 0.5f, 1f );
|
|
44
|
+
rectTransform.anchoredPosition = new Vector3 ( 0.5f, -100f, 0 );
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
{
|
|
48
|
+
rectTransform.anchorMin = new Vector2 ( 0.5f, 0 );
|
|
49
|
+
rectTransform.anchorMax = new Vector2 ( 0.5f, 0 );
|
|
50
|
+
rectTransform.anchoredPosition = new Vector3 ( 0.5f, 100f, 0 );
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private static void RemoveClone ( GameObject clone, Time time )
|
|
55
|
+
{
|
|
56
|
+
if (time == Time.oneSecond)
|
|
57
|
+
{
|
|
58
|
+
Destroy ( clone.gameObject, 1f );
|
|
59
|
+
}
|
|
60
|
+
else if (time == Time.twoSecond)
|
|
61
|
+
{
|
|
62
|
+
Destroy ( clone.gameObject, 2f );
|
|
63
|
+
}
|
|
64
|
+
else
|
|
65
|
+
{
|
|
66
|
+
Destroy ( clone.gameObject, 3f );
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
fileFormatVersion: 2
|
|
2
|
+
guid: 87a6eaa9efa41844890325132c22595a
|
|
3
|
+
timeCreated: 1532842822
|
|
4
|
+
licenseType: Free
|
|
5
|
+
MonoImporter:
|
|
6
|
+
externalObjects: {}
|
|
7
|
+
serializedVersion: 2
|
|
8
|
+
defaultReferences: []
|
|
9
|
+
executionOrder: 0
|
|
10
|
+
icon: {instanceID: 0}
|
|
11
|
+
userData:
|
|
12
|
+
assetBundleName:
|
|
13
|
+
assetBundleVariant:
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using Newtonsoft.Json;
|
|
4
|
+
|
|
5
|
+
namespace TapSDK.Core.Standalone.Internal.Bean
|
|
6
|
+
{
|
|
7
|
+
[Serializable]
|
|
8
|
+
internal class TapGatekeeper
|
|
9
|
+
{
|
|
10
|
+
[JsonProperty("switch")]
|
|
11
|
+
public TapGatekeeperSwitch Switch { get; set; } = new TapGatekeeperSwitch();
|
|
12
|
+
|
|
13
|
+
[JsonProperty("urls")]
|
|
14
|
+
public Dictionary<string, Url> Urls { get; set; }
|
|
15
|
+
|
|
16
|
+
[JsonProperty("taptap_app_id")]
|
|
17
|
+
public int? TapTapAppId { get; set; }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[Serializable]
|
|
21
|
+
internal class TapGatekeeperSwitch
|
|
22
|
+
{
|
|
23
|
+
[JsonProperty("auto_event")]
|
|
24
|
+
public bool AutoEvent { get; set; } = true;
|
|
25
|
+
|
|
26
|
+
[JsonProperty("heartbeat")]
|
|
27
|
+
public bool Heartbeat { get; set; } = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[Serializable]
|
|
31
|
+
internal class Url
|
|
32
|
+
{
|
|
33
|
+
[JsonProperty("webview")]
|
|
34
|
+
public string WebView { get; set; }
|
|
35
|
+
|
|
36
|
+
[JsonProperty("browser")]
|
|
37
|
+
public string Browser { get; set; }
|
|
38
|
+
|
|
39
|
+
[JsonProperty("uri")]
|
|
40
|
+
public string TapUri { get; set; }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -8,8 +8,8 @@ namespace TapSDK.Core.Standalone.Internal {
|
|
|
8
8
|
public static readonly string PROPERTY_ADD_TYPE = "add";
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
public readonly static string
|
|
12
|
-
public readonly static string
|
|
11
|
+
public readonly static string SERVER_URL_CN = "https://e.tapdb.net";
|
|
12
|
+
public readonly static string SERVER_URL_IO = "https://e.tapdb.ap-sg.tapapis.com";
|
|
13
13
|
public readonly static string DEVICE_LOGIN = "device_login";
|
|
14
14
|
public readonly static string USER_LOGIN = "user_login";
|
|
15
15
|
|
|
@@ -7,23 +7,35 @@ using System.Linq;
|
|
|
7
7
|
using System.Text;
|
|
8
8
|
using System.Threading;
|
|
9
9
|
using System.Threading.Tasks;
|
|
10
|
+
using TapSDK.Core.Internal.Log;
|
|
11
|
+
using TapSDK.Core.Standalone.Internal.Http;
|
|
10
12
|
using UnityEngine;
|
|
11
13
|
using UnityEngine.Networking;
|
|
12
14
|
|
|
13
|
-
namespace TapSDK.Core.Standalone.Internal
|
|
15
|
+
namespace TapSDK.Core.Standalone.Internal
|
|
16
|
+
{
|
|
14
17
|
public class EventSender : MonoBehaviour
|
|
15
18
|
{
|
|
16
19
|
private const string EventFilePath = "events.json";
|
|
20
|
+
|
|
21
|
+
private readonly TapLog log = new TapLog("TapEvent");
|
|
17
22
|
private string persistentDataPath = Application.persistentDataPath;
|
|
18
|
-
|
|
23
|
+
|
|
19
24
|
private Queue<Dictionary<string, object>> eventQueue = new Queue<Dictionary<string, object>>();
|
|
20
|
-
private
|
|
25
|
+
private TapHttp tapHttp = TapHttp
|
|
26
|
+
.NewBuilder("TapSDKCore", TapTapSDK.Version)
|
|
27
|
+
.Sign(TapHttpSign.CreateNoneSign())
|
|
28
|
+
.Parser(TapHttpParser.CreateEventParser())
|
|
29
|
+
.Build();
|
|
30
|
+
|
|
21
31
|
private const int MaxEvents = 50;
|
|
22
32
|
private const int MaxBatchSize = 200;
|
|
23
33
|
private const float SendInterval = 15f;
|
|
24
34
|
private Timer timer;
|
|
25
35
|
private DateTime lastSendTime;
|
|
26
36
|
|
|
37
|
+
private string domain = Constants.SERVER_URL_CN;
|
|
38
|
+
|
|
27
39
|
private int QueueCount => eventQueue.Count;
|
|
28
40
|
|
|
29
41
|
public EventSender()
|
|
@@ -39,12 +51,13 @@ namespace TapSDK.Core.Standalone.Internal {
|
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
var coreOptions = TapCoreStandalone.coreOptions;
|
|
42
|
-
if(coreOptions.region == TapTapRegionType.CN)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
if (coreOptions.region == TapTapRegionType.CN)
|
|
55
|
+
{
|
|
56
|
+
domain = Constants.SERVER_URL_CN;
|
|
57
|
+
}
|
|
58
|
+
else
|
|
59
|
+
{
|
|
60
|
+
domain = Constants.SERVER_URL_IO;
|
|
48
61
|
}
|
|
49
62
|
|
|
50
63
|
// 加载未发送的事件
|
|
@@ -60,7 +73,7 @@ namespace TapSDK.Core.Standalone.Internal {
|
|
|
60
73
|
return;
|
|
61
74
|
}
|
|
62
75
|
|
|
63
|
-
var
|
|
76
|
+
var eventsToSend = new List<Dictionary<string, object>>();
|
|
64
77
|
for (int i = 0; i < MaxBatchSize && eventQueue.Count > 0; i++)
|
|
65
78
|
{
|
|
66
79
|
eventsToSend.Add(eventQueue.Dequeue());
|
|
@@ -70,21 +83,20 @@ namespace TapSDK.Core.Standalone.Internal {
|
|
|
70
83
|
{ "data", eventsToSend }
|
|
71
84
|
};
|
|
72
85
|
|
|
73
|
-
var resonse = await
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
86
|
+
var resonse = await tapHttp.PostJsonAsync<Boolean>(path: $"{domain}/v2/batch", json: body);
|
|
87
|
+
if (resonse.IsSuccess)
|
|
88
|
+
{
|
|
89
|
+
log.Log("Events sent successfully");
|
|
90
|
+
}
|
|
91
|
+
else
|
|
77
92
|
{
|
|
93
|
+
log.Warning("Failed to send events");
|
|
78
94
|
// 将事件重新添加到队列
|
|
79
95
|
foreach (var eventParams in eventsToSend)
|
|
80
96
|
{
|
|
81
97
|
eventQueue.Enqueue(eventParams);
|
|
82
98
|
}
|
|
83
99
|
}
|
|
84
|
-
else
|
|
85
|
-
{
|
|
86
|
-
Debug.Log("Events sent successfully");
|
|
87
|
-
}
|
|
88
100
|
onSendComplete?.Invoke();
|
|
89
101
|
SaveEvents();
|
|
90
102
|
}
|
|
@@ -129,7 +141,6 @@ namespace TapSDK.Core.Standalone.Internal {
|
|
|
129
141
|
{
|
|
130
142
|
return;
|
|
131
143
|
}
|
|
132
|
-
|
|
133
144
|
var savedEvents = ConvertToListOfDictionaries(Json.Deserialize(jsonData));
|
|
134
145
|
if (savedEvents == null)
|
|
135
146
|
{
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
using System.Net.Http;
|
|
2
|
+
|
|
3
|
+
namespace TapSDK.Core.Standalone.Internal.Http
|
|
4
|
+
{
|
|
5
|
+
using System;
|
|
6
|
+
using System.Collections.Generic;
|
|
7
|
+
using System.Net.Http.Headers;
|
|
8
|
+
using System.Threading.Tasks;
|
|
9
|
+
using System.Web;
|
|
10
|
+
using Newtonsoft.Json;
|
|
11
|
+
using TapSDK.Core.Internal.Log;
|
|
12
|
+
|
|
13
|
+
public class TapHttp
|
|
14
|
+
{
|
|
15
|
+
|
|
16
|
+
private static readonly string TAG = "Http";
|
|
17
|
+
|
|
18
|
+
private static readonly int MAX_GET_RETRY_COUNT = 3;
|
|
19
|
+
|
|
20
|
+
internal static readonly long CONNECT_TIMEOUT_MILLIS = 10 * 1000L;
|
|
21
|
+
internal static readonly long READ_TIMEOUT_MILLIS = 5 * 1000L;
|
|
22
|
+
internal static readonly long WRITE_TIMEOUT_MILLIS = 5 * 1000L;
|
|
23
|
+
|
|
24
|
+
public static readonly string HOST_CN = "https://tapsdk.tapapis.cn";
|
|
25
|
+
public static readonly string HOST_IO = "https://tapsdk.tapapis.com";
|
|
26
|
+
|
|
27
|
+
private static HttpClient client = new HttpClient();
|
|
28
|
+
|
|
29
|
+
private readonly TapHttpConfig httpConfig;
|
|
30
|
+
|
|
31
|
+
private readonly TapLog log = new TapLog(TAG);
|
|
32
|
+
|
|
33
|
+
private TapHttp() { }
|
|
34
|
+
|
|
35
|
+
internal TapHttp(TapHttpConfig httpConfig)
|
|
36
|
+
{
|
|
37
|
+
this.httpConfig = httpConfig;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public static TapHttpBuilder NewBuilder(string moduleName, string moduleVersion)
|
|
41
|
+
{
|
|
42
|
+
return new TapHttpBuilder(moduleName, moduleVersion);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public async void PostJson<T>(
|
|
46
|
+
string url,
|
|
47
|
+
Dictionary<string, string> headers = null,
|
|
48
|
+
Dictionary<string, string> queryParams = null,
|
|
49
|
+
Dictionary<string, object> json = null,
|
|
50
|
+
bool enableAuthorization = false,
|
|
51
|
+
ITapHttpRetryStrategy retryStrategy = null,
|
|
52
|
+
Action<T> onSuccess = null,
|
|
53
|
+
Action<AbsTapHttpException> onFailure = null)
|
|
54
|
+
{
|
|
55
|
+
TapHttpResult<T> tapHttpResult = await PostJsonAsync<T>(
|
|
56
|
+
path: url,
|
|
57
|
+
headers: headers,
|
|
58
|
+
queryParams: queryParams,
|
|
59
|
+
json: json,
|
|
60
|
+
enableAuthorization: enableAuthorization,
|
|
61
|
+
retryStrategy: retryStrategy
|
|
62
|
+
);
|
|
63
|
+
if (tapHttpResult.IsSuccess)
|
|
64
|
+
{
|
|
65
|
+
onSuccess?.Invoke(tapHttpResult.Data);
|
|
66
|
+
}
|
|
67
|
+
else
|
|
68
|
+
{
|
|
69
|
+
onFailure?.Invoke(tapHttpResult.HttpException);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public async void PostForm<T>(
|
|
74
|
+
string url,
|
|
75
|
+
Dictionary<string, string> headers = null,
|
|
76
|
+
Dictionary<string, string> queryParams = null,
|
|
77
|
+
Dictionary<string, string> form = null,
|
|
78
|
+
bool enableAuthorization = false,
|
|
79
|
+
ITapHttpRetryStrategy retryStrategy = null,
|
|
80
|
+
Action<T> onSuccess = null,
|
|
81
|
+
Action<AbsTapHttpException> onFailure = null)
|
|
82
|
+
{
|
|
83
|
+
TapHttpResult<T> tapHttpResult = await PostFormAsync<T>(
|
|
84
|
+
url: url,
|
|
85
|
+
headers: headers,
|
|
86
|
+
queryParams: queryParams,
|
|
87
|
+
form: form,
|
|
88
|
+
enableAuthorization: enableAuthorization,
|
|
89
|
+
retryStrategy: retryStrategy
|
|
90
|
+
);
|
|
91
|
+
if (tapHttpResult.IsSuccess)
|
|
92
|
+
{
|
|
93
|
+
onSuccess?.Invoke(tapHttpResult.Data);
|
|
94
|
+
}
|
|
95
|
+
else
|
|
96
|
+
{
|
|
97
|
+
onFailure?.Invoke(tapHttpResult.HttpException);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public async void Get<T>(
|
|
102
|
+
string url,
|
|
103
|
+
Dictionary<string, string> headers = null,
|
|
104
|
+
Dictionary<string, string> queryParams = null,
|
|
105
|
+
bool enableAuthorization = false,
|
|
106
|
+
ITapHttpRetryStrategy retryStrategy = null,
|
|
107
|
+
Action<T> onSuccess = null,
|
|
108
|
+
Action<Exception> onFailure = null
|
|
109
|
+
)
|
|
110
|
+
{
|
|
111
|
+
TapHttpResult<T> tapHttpResult = await GetAsync<T>(
|
|
112
|
+
url: url,
|
|
113
|
+
headers: headers,
|
|
114
|
+
queryParams: queryParams,
|
|
115
|
+
enableAuthorization: enableAuthorization,
|
|
116
|
+
retryStrategy: retryStrategy
|
|
117
|
+
);
|
|
118
|
+
if (tapHttpResult.IsSuccess)
|
|
119
|
+
{
|
|
120
|
+
onSuccess?.Invoke(tapHttpResult.Data);
|
|
121
|
+
}
|
|
122
|
+
else
|
|
123
|
+
{
|
|
124
|
+
onFailure?.Invoke(tapHttpResult.HttpException);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public async Task<TapHttpResult<T>> GetAsync<T>(
|
|
129
|
+
string url,
|
|
130
|
+
Dictionary<string, string> headers = null,
|
|
131
|
+
Dictionary<string, string> queryParams = null,
|
|
132
|
+
bool enableAuthorization = false,
|
|
133
|
+
ITapHttpRetryStrategy retryStrategy = null
|
|
134
|
+
)
|
|
135
|
+
{
|
|
136
|
+
if (retryStrategy == null)
|
|
137
|
+
{
|
|
138
|
+
retryStrategy = TapHttpRetryStrategy.CreateDefault(TapHttpBackoffStrategy.CreateFixed(MAX_GET_RETRY_COUNT));
|
|
139
|
+
}
|
|
140
|
+
return await Request<T>(
|
|
141
|
+
url: url,
|
|
142
|
+
method: HttpMethod.Get,
|
|
143
|
+
enableAuthorization: enableAuthorization,
|
|
144
|
+
retryStrategy: retryStrategy,
|
|
145
|
+
headers: headers,
|
|
146
|
+
queryParams: queryParams
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public async Task<TapHttpResult<T>> PostJsonAsync<T>(
|
|
151
|
+
string path,
|
|
152
|
+
Dictionary<string, string> headers = null,
|
|
153
|
+
Dictionary<string, string> queryParams = null,
|
|
154
|
+
object json = null,
|
|
155
|
+
bool enableAuthorization = false,
|
|
156
|
+
ITapHttpRetryStrategy retryStrategy = null
|
|
157
|
+
)
|
|
158
|
+
{
|
|
159
|
+
if (retryStrategy == null)
|
|
160
|
+
{
|
|
161
|
+
retryStrategy = TapHttpRetryStrategy.CreateDefault(TapHttpBackoffStrategy.CreateNone());
|
|
162
|
+
}
|
|
163
|
+
string jsonStr = null;
|
|
164
|
+
if (json != null)
|
|
165
|
+
{
|
|
166
|
+
jsonStr = await Task.Run(() => JsonConvert.SerializeObject(json));
|
|
167
|
+
}
|
|
168
|
+
return await Request<T>(
|
|
169
|
+
url: path,
|
|
170
|
+
method: HttpMethod.Post,
|
|
171
|
+
enableAuthorization: enableAuthorization,
|
|
172
|
+
retryStrategy: retryStrategy,
|
|
173
|
+
headers: headers,
|
|
174
|
+
queryParams: queryParams,
|
|
175
|
+
body: jsonStr
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public async Task<TapHttpResult<T>> PostFormAsync<T>(
|
|
180
|
+
string url,
|
|
181
|
+
Dictionary<string, string> headers = null,
|
|
182
|
+
Dictionary<string, string> queryParams = null,
|
|
183
|
+
Dictionary<string, string> form = null,
|
|
184
|
+
bool enableAuthorization = false,
|
|
185
|
+
ITapHttpRetryStrategy retryStrategy = null
|
|
186
|
+
)
|
|
187
|
+
{
|
|
188
|
+
if (retryStrategy == null)
|
|
189
|
+
{
|
|
190
|
+
retryStrategy = TapHttpRetryStrategy.CreateDefault(TapHttpBackoffStrategy.CreateNone());
|
|
191
|
+
}
|
|
192
|
+
return await Request<T>(
|
|
193
|
+
url: url,
|
|
194
|
+
method: HttpMethod.Post,
|
|
195
|
+
enableAuthorization: enableAuthorization,
|
|
196
|
+
retryStrategy: retryStrategy,
|
|
197
|
+
headers: headers,
|
|
198
|
+
queryParams: queryParams,
|
|
199
|
+
body: form
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private async Task<TapHttpResult<T>> Request<T>(
|
|
204
|
+
string url,
|
|
205
|
+
HttpMethod method,
|
|
206
|
+
bool enableAuthorization,
|
|
207
|
+
ITapHttpRetryStrategy retryStrategy,
|
|
208
|
+
Dictionary<string, string> headers = null,
|
|
209
|
+
Dictionary<string, string> queryParams = null,
|
|
210
|
+
object body = null
|
|
211
|
+
)
|
|
212
|
+
{
|
|
213
|
+
TapHttpResult<T> tapHttpResult;
|
|
214
|
+
long nextRetryMillis;
|
|
215
|
+
do
|
|
216
|
+
{
|
|
217
|
+
tapHttpResult = await RequestInner<T>(url, method, enableAuthorization, headers, queryParams, body);
|
|
218
|
+
|
|
219
|
+
if (tapHttpResult.IsSuccess)
|
|
220
|
+
{
|
|
221
|
+
return tapHttpResult;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
nextRetryMillis = retryStrategy.NextRetryMillis(tapHttpResult.HttpException);
|
|
225
|
+
if (nextRetryMillis > 0)
|
|
226
|
+
{
|
|
227
|
+
log.Log($"Request failed, retry after {nextRetryMillis} ms");
|
|
228
|
+
await Task.Delay(TimeSpan.FromMilliseconds(nextRetryMillis));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
} while (nextRetryMillis >= 0L);
|
|
232
|
+
|
|
233
|
+
return tapHttpResult;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private async Task<TapHttpResult<T>> RequestInner<T>(
|
|
237
|
+
string path,
|
|
238
|
+
HttpMethod method,
|
|
239
|
+
bool enableAuthorization,
|
|
240
|
+
Dictionary<string, string> headers = null,
|
|
241
|
+
Dictionary<string, string> queryParams = null,
|
|
242
|
+
object body = null
|
|
243
|
+
)
|
|
244
|
+
{
|
|
245
|
+
// 处理查询参数
|
|
246
|
+
Dictionary<string, string> allQueryParams = new Dictionary<string, string>();
|
|
247
|
+
if (queryParams != null)
|
|
248
|
+
{
|
|
249
|
+
foreach (var param in queryParams)
|
|
250
|
+
{
|
|
251
|
+
allQueryParams[param.Key] = param.Value;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
var fixedQueryParams = httpConfig.Sign.GetFixedQueryParams();
|
|
255
|
+
if (fixedQueryParams != null)
|
|
256
|
+
{
|
|
257
|
+
foreach (var param in fixedQueryParams)
|
|
258
|
+
{
|
|
259
|
+
allQueryParams[param.Key] = param.Value;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
string host = HOST_CN;
|
|
263
|
+
if (httpConfig.Domain != null)
|
|
264
|
+
{
|
|
265
|
+
host = httpConfig.Domain;
|
|
266
|
+
}
|
|
267
|
+
else
|
|
268
|
+
{
|
|
269
|
+
if (TapCoreStandalone.coreOptions.region == TapTapRegionType.CN)
|
|
270
|
+
{
|
|
271
|
+
host = HOST_CN;
|
|
272
|
+
}
|
|
273
|
+
else if (TapCoreStandalone.coreOptions.region == TapTapRegionType.Overseas)
|
|
274
|
+
{
|
|
275
|
+
host = HOST_IO;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// 拼接查询参数
|
|
279
|
+
UriBuilder uriBuilder;
|
|
280
|
+
if (path.StartsWith("http://") || path.StartsWith("https://"))
|
|
281
|
+
{
|
|
282
|
+
uriBuilder = new UriBuilder(path);
|
|
283
|
+
}
|
|
284
|
+
else
|
|
285
|
+
{
|
|
286
|
+
if (!path.StartsWith("/"))
|
|
287
|
+
{
|
|
288
|
+
path = "/" + path;
|
|
289
|
+
}
|
|
290
|
+
uriBuilder = new UriBuilder(uri: $"{host}{path}");
|
|
291
|
+
}
|
|
292
|
+
if (allQueryParams.Count > 0)
|
|
293
|
+
{
|
|
294
|
+
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
|
|
295
|
+
foreach (var param in allQueryParams)
|
|
296
|
+
{
|
|
297
|
+
query[param.Key] = param.Value.ToString();
|
|
298
|
+
}
|
|
299
|
+
uriBuilder.Query = query.ToString();
|
|
300
|
+
}
|
|
301
|
+
var requestUri = uriBuilder.Uri;
|
|
302
|
+
|
|
303
|
+
// 创建 HttpRequestMessage
|
|
304
|
+
var request = new HttpRequestMessage
|
|
305
|
+
{
|
|
306
|
+
Method = method,
|
|
307
|
+
RequestUri = requestUri
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// 处理请求头
|
|
311
|
+
Dictionary<string, string> allHeaders = new Dictionary<string, string>();
|
|
312
|
+
if (headers != null)
|
|
313
|
+
{
|
|
314
|
+
foreach (var header in headers)
|
|
315
|
+
{
|
|
316
|
+
allHeaders[header.Key] = header.Value;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
Dictionary<string, string> fixedHeaders = httpConfig.Sign.GetFixedHeaders(requestUri.ToString(), method, httpConfig.ModuleName, httpConfig.ModuleVersion, enableAuthorization);
|
|
320
|
+
if (fixedHeaders != null)
|
|
321
|
+
{
|
|
322
|
+
foreach (var header in fixedHeaders)
|
|
323
|
+
{
|
|
324
|
+
allHeaders[header.Key] = header.Value;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// 添加请求头
|
|
328
|
+
if (allHeaders != null)
|
|
329
|
+
{
|
|
330
|
+
foreach (var header in allHeaders)
|
|
331
|
+
{
|
|
332
|
+
request.Headers.TryAddWithoutValidation(header.Key, header.Value.ToString());
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// 根据请求类型设置请求体
|
|
337
|
+
if (method == HttpMethod.Post || method == HttpMethod.Put)
|
|
338
|
+
{
|
|
339
|
+
if (body != null)
|
|
340
|
+
{
|
|
341
|
+
if (body is string jsonBody) // 处理 JSON 数据
|
|
342
|
+
{
|
|
343
|
+
StringContent requestContent = new StringContent(jsonBody);
|
|
344
|
+
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
|
345
|
+
request.Content = requestContent;
|
|
346
|
+
}
|
|
347
|
+
else if (body is Dictionary<string, string> formData) // 处理 Form 数据
|
|
348
|
+
{
|
|
349
|
+
request.Content = new FormUrlEncodedContent(formData);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// 签算
|
|
354
|
+
httpConfig.Sign.Sign(request);
|
|
355
|
+
try
|
|
356
|
+
{
|
|
357
|
+
if (TapTapSDK.taptapSdkOptions.enableLog)
|
|
358
|
+
{
|
|
359
|
+
TapHttpUtils.PrintRequest(client, request, request.Content.ReadAsStringAsync().Result);
|
|
360
|
+
}
|
|
361
|
+
// 发送请求
|
|
362
|
+
HttpResponseMessage response = await client.SendAsync(request);
|
|
363
|
+
if (TapTapSDK.taptapSdkOptions.enableLog)
|
|
364
|
+
{
|
|
365
|
+
TapHttpUtils.PrintResponse(response, response.Content.ReadAsStringAsync().Result);
|
|
366
|
+
}
|
|
367
|
+
// 解析响应
|
|
368
|
+
return await httpConfig.Parser.Parse<T>(response);
|
|
369
|
+
}
|
|
370
|
+
catch (Exception ex)
|
|
371
|
+
{
|
|
372
|
+
// 捕获并处理请求异常
|
|
373
|
+
return TapHttpResult<T>.UnknownFailure(new TapHttpUnknownException(ex));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|