Initial commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da41148b575cc423dbe6d514b5cb9a88
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public interface IUnityKeyValueStore
|
||||
{
|
||||
string GetString(string key);
|
||||
void SetString(string key, string value);
|
||||
void DeleteKey(string key);
|
||||
void Save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6b223b25f3c9492b8f0d7d75528a4b2
|
||||
@@ -0,0 +1,9 @@
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public interface IUnityLoggerSink
|
||||
{
|
||||
void Log(RudderLogLevel level, string message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec59e2140dfdd453ca968c21c67f6554
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public interface IUnityRequestExecutor
|
||||
{
|
||||
Task<string> SendAsync(
|
||||
string method,
|
||||
string url,
|
||||
string body,
|
||||
IReadOnlyDictionary<string, string> headers,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e634b1eed56bc4eb4afce1f4558623a5
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal sealed class UnityRequestException : Exception
|
||||
{
|
||||
public int StatusCode { get; }
|
||||
public string ResponseBody { get; }
|
||||
|
||||
public UnityRequestException(int statusCode, string responseBody, string message)
|
||||
: base(message)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
ResponseBody = responseBody;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f76d30c3864c428cbc217d51ea84c224
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public sealed class PlayerPrefsUnityKeyValueStore : IUnityKeyValueStore
|
||||
{
|
||||
private readonly SynchronizationContext _unityContext;
|
||||
private readonly int _mainThreadId;
|
||||
|
||||
public PlayerPrefsUnityKeyValueStore()
|
||||
{
|
||||
_unityContext = SynchronizationContext.Current;
|
||||
_mainThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
}
|
||||
|
||||
public string GetString(string key)
|
||||
{
|
||||
return RunOnMainThread(() =>
|
||||
{
|
||||
var value = PlayerPrefs.GetString(key, string.Empty);
|
||||
return string.IsNullOrEmpty(value) ? null : value;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetString(string key, string value)
|
||||
{
|
||||
RunOnMainThread(() => PlayerPrefs.SetString(key, value));
|
||||
}
|
||||
|
||||
public void DeleteKey(string key)
|
||||
{
|
||||
RunOnMainThread(() => PlayerPrefs.DeleteKey(key));
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
RunOnMainThread(PlayerPrefs.Save);
|
||||
}
|
||||
|
||||
private void RunOnMainThread(Action action)
|
||||
{
|
||||
RunOnMainThread(() =>
|
||||
{
|
||||
action();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private T RunOnMainThread<T>(Func<T> action)
|
||||
{
|
||||
if (Thread.CurrentThread.ManagedThreadId == _mainThreadId || _unityContext == null)
|
||||
return action();
|
||||
|
||||
T result = default;
|
||||
Exception captured = null;
|
||||
using (var completed = new ManualResetEventSlim(false))
|
||||
{
|
||||
_unityContext.Post(_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
result = action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
captured = ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
completed.Set();
|
||||
}
|
||||
}, null);
|
||||
|
||||
completed.Wait();
|
||||
}
|
||||
|
||||
if (captured != null)
|
||||
throw captured;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac69b887beaca42f285a77a665f01fe5
|
||||
@@ -0,0 +1,30 @@
|
||||
using RudderSdk.Core;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public static class RudderUnityClientFactory
|
||||
{
|
||||
public static RudderClient Create(RudderUnityClientOptions options)
|
||||
{
|
||||
var executor = options.RequestExecutor ?? new UnityWebRequestExecutor(options.TimeoutSeconds);
|
||||
|
||||
var clientOptions = new RudderClientOptions
|
||||
{
|
||||
BaseUrl = options.BaseUrl,
|
||||
RealtimeUrl = options.RealtimeUrl,
|
||||
ProjectKey = options.ProjectKey,
|
||||
Logger = new UnityLoggerAdapter(options.LoggerSink ?? new UnityDebugLoggerSink()),
|
||||
Transport = new UnityTransportAdapter(options.BaseUrl, executor),
|
||||
UploadTransport = new UnityUploadTransport(options.TimeoutSeconds),
|
||||
TokenStore = new UnityTokenStoreAdapter(options.KeyValueStore),
|
||||
DeviceIdProvider = new UnityDeviceIdProvider(),
|
||||
Clock = new UnityClock(),
|
||||
PlanStateStore = new UnityPlanStateStore(options.KeyValueStore),
|
||||
Scheduler = new UnityPlanScheduler(),
|
||||
RealtimeTransportFactory = new UnityRealtimeTransportFactory()
|
||||
};
|
||||
|
||||
return new RudderClient(clientOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68a7c35de38af47bead080881b0c6838
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public class RudderUnityClientOptions
|
||||
{
|
||||
public string BaseUrl { get; set; }
|
||||
public string RealtimeUrl { get; set; }
|
||||
public string ProjectKey { get; set; }
|
||||
public int TimeoutSeconds { get; set; } = 10;
|
||||
public IUnityKeyValueStore KeyValueStore { get; set; }
|
||||
public IUnityRequestExecutor RequestExecutor { get; set; }
|
||||
public IUnityLoggerSink LoggerSink { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac789e74241fd4763bf08271729f15fa
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal class UnityClock : IClock
|
||||
{
|
||||
public DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeb86d121ee7e4310be96a604cffa692
|
||||
@@ -0,0 +1,24 @@
|
||||
using RudderSdk.Core.Abstractions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public sealed class UnityDebugLoggerSink : IUnityLoggerSink
|
||||
{
|
||||
public void Log(RudderLogLevel level, string message)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case RudderLogLevel.Warning:
|
||||
Debug.LogWarning("[Rudder] " + message);
|
||||
break;
|
||||
case RudderLogLevel.Error:
|
||||
Debug.LogError("[Rudder] " + message);
|
||||
break;
|
||||
default:
|
||||
Debug.Log("[Rudder] " + message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b30348f9b01a04e4c90e8ba3a06da65b
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal class UnityDeviceIdProvider : IDeviceIdProvider
|
||||
{
|
||||
public string DeviceId => SystemInfoHelper.GetDeviceId();
|
||||
}
|
||||
|
||||
internal static class SystemInfoHelper
|
||||
{
|
||||
private static string _cachedDeviceId;
|
||||
|
||||
public static string GetDeviceId()
|
||||
{
|
||||
if (_cachedDeviceId != null) return _cachedDeviceId;
|
||||
_cachedDeviceId = UnityEngine.PlayerPrefs.GetString("rudder_device_id", null);
|
||||
if (string.IsNullOrEmpty(_cachedDeviceId))
|
||||
{
|
||||
_cachedDeviceId = Guid.NewGuid().ToString("N");
|
||||
UnityEngine.PlayerPrefs.SetString("rudder_device_id", _cachedDeviceId);
|
||||
UnityEngine.PlayerPrefs.Save();
|
||||
}
|
||||
return _cachedDeviceId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3555b2a84c5b4e0d80113f1af9c47b0
|
||||
@@ -0,0 +1,13 @@
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal class UnityLoggerAdapter : IRudderLogger
|
||||
{
|
||||
private readonly IUnityLoggerSink _sink;
|
||||
|
||||
public UnityLoggerAdapter(IUnityLoggerSink sink) => _sink = sink;
|
||||
|
||||
public void Log(RudderLogLevel level, string message) => _sink.Log(level, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e38911c13bcb54553a58bbda0fb20f1f
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal class UnityPlanScheduler : IPlanScheduler
|
||||
{
|
||||
public Task ScheduleAsync(TimeSpan delay, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.Delay(delay, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4f8e4e8237be445c96672d96294c6c7
|
||||
@@ -0,0 +1,30 @@
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal class UnityPlanStateStore : IPlanStateStore
|
||||
{
|
||||
private const string KEY = "liveops_plan_runner_state";
|
||||
|
||||
private readonly IUnityKeyValueStore _store;
|
||||
|
||||
public UnityPlanStateStore(IUnityKeyValueStore store)
|
||||
{
|
||||
_store = store;
|
||||
}
|
||||
|
||||
public string State
|
||||
{
|
||||
get => _store.GetString(KEY);
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
_store.DeleteKey(KEY);
|
||||
else
|
||||
_store.SetString(KEY, value);
|
||||
|
||||
_store.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 118ea3286be8b4daab53eaf7885507a0
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal sealed class UnityRealtimeTransportFactory : IRealtimeTransportFactory
|
||||
{
|
||||
public IRealtimeTransport Create()
|
||||
{
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
return new UnityRealtimeTransport(new JsWebSocketAdapter());
|
||||
#else
|
||||
return new UnityRealtimeTransport(new NativeWebSocketAdapter());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class UnityRealtimeTransport : IRealtimeTransport
|
||||
{
|
||||
private readonly IWebSocketAdapter _adapter;
|
||||
|
||||
public UnityRealtimeTransport(IWebSocketAdapter adapter)
|
||||
{
|
||||
_adapter = adapter;
|
||||
_adapter.Closed += () => Closed?.Invoke();
|
||||
_adapter.Received += data => Received?.Invoke(data);
|
||||
_adapter.ReceivedError += ex => Error?.Invoke(ex);
|
||||
}
|
||||
|
||||
public event Action Closed;
|
||||
public event Action<ArraySegment<byte>> Received;
|
||||
public event Action<Exception> Error;
|
||||
|
||||
public bool IsConnected => _adapter.IsConnected;
|
||||
|
||||
public Task ConnectAsync(Uri uri, TimeSpan timeout, CancellationToken cancellationToken = default)
|
||||
=> _adapter.ConnectAsync(uri, (int)Math.Ceiling(timeout.TotalSeconds), cancellationToken);
|
||||
|
||||
public Task SendAsync(ArraySegment<byte> data, CancellationToken cancellationToken = default)
|
||||
=> _adapter.SendAsync(data, cancellationToken);
|
||||
|
||||
public Task CloseAsync(CancellationToken cancellationToken = default)
|
||||
=> _adapter.CloseAsync();
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be75d4878806d40648e49338f0ecd508
|
||||
@@ -0,0 +1,28 @@
|
||||
using RudderSdk.Core.Abstractions;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal class UnityTokenStoreAdapter : ITokenStore
|
||||
{
|
||||
private readonly IUnityKeyValueStore _store;
|
||||
|
||||
public UnityTokenStoreAdapter(IUnityKeyValueStore store) => _store = store;
|
||||
|
||||
public string GetAccessToken() => _store.GetString("liveops_access_token");
|
||||
public string GetRefreshToken() => _store.GetString("liveops_refresh_token");
|
||||
|
||||
public void SaveTokens(string accessToken, string refreshToken)
|
||||
{
|
||||
_store.SetString("liveops_access_token", accessToken);
|
||||
_store.SetString("liveops_refresh_token", refreshToken);
|
||||
_store.Save();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_store.DeleteKey("liveops_access_token");
|
||||
_store.DeleteKey("liveops_refresh_token");
|
||||
_store.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f25169510865d4391b518bb7e8b7a36f
|
||||
@@ -0,0 +1,91 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using RudderSdk.Core;
|
||||
using RudderSdk.Core.Abstractions;
|
||||
using RudderSdk.Core.Models;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal class UnityTransportAdapter : IRudderTransport
|
||||
{
|
||||
private readonly string _baseUrl;
|
||||
private readonly IUnityRequestExecutor _executor;
|
||||
|
||||
public UnityTransportAdapter(string baseUrl, IUnityRequestExecutor executor)
|
||||
{
|
||||
_baseUrl = baseUrl.TrimEnd('/');
|
||||
_executor = executor;
|
||||
}
|
||||
|
||||
public async Task<TResponse> SendAsync<TRequest, TResponse>(
|
||||
string method,
|
||||
string path,
|
||||
TRequest request,
|
||||
string accessToken,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var headers = new Dictionary<string, string>
|
||||
{
|
||||
["Content-Type"] = "application/json"
|
||||
};
|
||||
if (!string.IsNullOrEmpty(accessToken))
|
||||
headers["Authorization"] = "Bearer " + accessToken;
|
||||
|
||||
var body = request != null ? JsonConvert.SerializeObject(request) : null;
|
||||
|
||||
string responseJson;
|
||||
try
|
||||
{
|
||||
responseJson = await _executor.SendAsync(
|
||||
method, _baseUrl + path, body, headers, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (UnityRequestException exception)
|
||||
{
|
||||
throw MapError(exception);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(responseJson))
|
||||
return default;
|
||||
|
||||
return JsonConvert.DeserializeObject<TResponse>(responseJson);
|
||||
}
|
||||
|
||||
private static RudderApiException MapError(UnityRequestException exception)
|
||||
{
|
||||
string code = null;
|
||||
string message = null;
|
||||
string requestId = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(exception.ResponseBody))
|
||||
{
|
||||
try
|
||||
{
|
||||
var error = JsonConvert.DeserializeObject<ErrorResponse>(exception.ResponseBody);
|
||||
code = error?.Code;
|
||||
message = error?.Error;
|
||||
requestId = error?.RequestId;
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(message))
|
||||
message = exception.Message;
|
||||
|
||||
switch (exception.StatusCode)
|
||||
{
|
||||
case 401:
|
||||
return new RudderAuthException(exception.StatusCode, code, message, requestId);
|
||||
case 404:
|
||||
return new RudderNotFoundException(exception.StatusCode, code, message, requestId);
|
||||
case 429:
|
||||
return new RudderRateLimitException(exception.StatusCode, code, message, requestId);
|
||||
default:
|
||||
return new RudderApiException(exception.StatusCode, code, message, requestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05e990dc7adb8430780c5d4652655725
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RudderSdk.Core;
|
||||
using RudderSdk.Core.Abstractions;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
internal sealed class UnityUploadTransport : IUploadTransport
|
||||
{
|
||||
private const int DefaultTimeoutSeconds = 10;
|
||||
|
||||
private readonly int _timeoutSeconds;
|
||||
|
||||
public UnityUploadTransport(int timeoutSeconds = DefaultTimeoutSeconds)
|
||||
{
|
||||
_timeoutSeconds = timeoutSeconds > 0 ? timeoutSeconds : DefaultTimeoutSeconds;
|
||||
}
|
||||
|
||||
public async Task PutAsync(string url, byte[] data, string contentType, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using (var request = UnityWebRequest.Put(url, data ?? System.Array.Empty<byte>()))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(contentType))
|
||||
request.SetRequestHeader("Content-Type", contentType);
|
||||
|
||||
request.timeout = _timeoutSeconds;
|
||||
|
||||
var operation = request.SendWebRequest();
|
||||
var completion = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
operation.completed += _ => completion.TrySetResult(true);
|
||||
|
||||
using (cancellationToken.Register(() =>
|
||||
{
|
||||
request.Abort();
|
||||
completion.TrySetCanceled(cancellationToken);
|
||||
}))
|
||||
{
|
||||
await completion.Task.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (request.result == UnityWebRequest.Result.ConnectionError)
|
||||
{
|
||||
throw new RudderNetworkException(request.error);
|
||||
}
|
||||
|
||||
if (request.result == UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
throw new RudderApiException(
|
||||
(int)request.responseCode,
|
||||
string.Empty,
|
||||
request.error + ": " + request.downloadHandler?.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 415e95ebea4594057990efb6707f3ebc
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RudderSdk.Core;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace RudderSdk.Unity
|
||||
{
|
||||
public sealed class UnityWebRequestExecutor : IUnityRequestExecutor
|
||||
{
|
||||
private const int DefaultTimeoutSeconds = 10;
|
||||
|
||||
private readonly int _timeoutSeconds;
|
||||
|
||||
public UnityWebRequestExecutor(int timeoutSeconds = DefaultTimeoutSeconds)
|
||||
{
|
||||
_timeoutSeconds = timeoutSeconds > 0 ? timeoutSeconds : DefaultTimeoutSeconds;
|
||||
}
|
||||
|
||||
public async Task<string> SendAsync(
|
||||
string method,
|
||||
string url,
|
||||
string body,
|
||||
IReadOnlyDictionary<string, string> headers,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using (var request = new UnityWebRequest(url, method))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(body))
|
||||
{
|
||||
var payload = System.Text.Encoding.UTF8.GetBytes(body);
|
||||
request.uploadHandler = new UploadHandlerRaw(payload);
|
||||
}
|
||||
|
||||
request.downloadHandler = new DownloadHandlerBuffer();
|
||||
request.timeout = _timeoutSeconds;
|
||||
|
||||
foreach (var header in headers)
|
||||
{
|
||||
request.SetRequestHeader(header.Key, header.Value);
|
||||
}
|
||||
|
||||
var operation = request.SendWebRequest();
|
||||
var completion = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
operation.completed += _ => completion.TrySetResult(true);
|
||||
|
||||
using (cancellationToken.Register(() => completion.TrySetCanceled(cancellationToken)))
|
||||
{
|
||||
await completion.Task;
|
||||
}
|
||||
|
||||
if (request.result == UnityWebRequest.Result.ConnectionError)
|
||||
{
|
||||
throw new RudderNetworkException(request.error);
|
||||
}
|
||||
|
||||
if (request.result == UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
var responseBody = request.downloadHandler.text;
|
||||
throw new UnityRequestException(
|
||||
(int)request.responseCode,
|
||||
responseBody,
|
||||
request.error + ": " + responseBody);
|
||||
}
|
||||
|
||||
return request.downloadHandler?.text ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13edd089b45e6405e97a5126b7772c1d
|
||||
Reference in New Issue
Block a user