diff --git a/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs b/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs index 8723876..88780ae 100644 --- a/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs +++ b/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs @@ -101,6 +101,8 @@ protected async Task Call( Debug.Log($"--> {method} {uri} [{www.responseCode}] {www.downloadHandler.text}"); } + await Talo.Continuity.HandlePostResponseHealthCheck(uri.ToString(), www.result); + if (www.result == UnityWebRequest.Result.Success) { return www.downloadHandler.text; diff --git a/Assets/Talo Game Services/Talo/Runtime/APIs/HealthCheckAPI.cs b/Assets/Talo Game Services/Talo/Runtime/APIs/HealthCheckAPI.cs index f4be5ed..246a685 100644 --- a/Assets/Talo Game Services/Talo/Runtime/APIs/HealthCheckAPI.cs +++ b/Assets/Talo Game Services/Talo/Runtime/APIs/HealthCheckAPI.cs @@ -4,23 +4,60 @@ namespace TaloGameServices { + public enum HealthCheckStatus + { + OK, + FAILED, + UNKNOWN + } + public class HealthCheckAPI : BaseAPI { + private HealthCheckStatus lastHealthCheckStatus = HealthCheckStatus.UNKNOWN; + public HealthCheckAPI() : base("v1/health-check") { } + public HealthCheckStatus GetLastStatus() + { + return lastHealthCheckStatus; + } + public async Task Ping() { var uri = new Uri(baseUrl); + bool success; try { await Call(uri, "GET"); - return true; - } catch + success = true; + } + catch { Debug.LogWarning("Health check failed"); - return false; + success = false; } + + bool failedLastHealthCheck = lastHealthCheckStatus == HealthCheckStatus.FAILED; + + if (success) + { + lastHealthCheckStatus = HealthCheckStatus.OK; + if (failedLastHealthCheck) + { + Talo.InvokeConnectionRestored(); + } + } + else + { + lastHealthCheckStatus = HealthCheckStatus.FAILED; + if (!failedLastHealthCheck) + { + Talo.InvokeConnectionLost(); + } + } + + return success; } } } diff --git a/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs b/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs index 927f3d0..b6898b1 100644 --- a/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs +++ b/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs @@ -14,7 +14,24 @@ public class PlayersAPI : BaseAPI private readonly string offlineDataPath = Application.persistentDataPath + "/ta.bin"; - public PlayersAPI() : base("v1/players") { } + public PlayersAPI() : base("v1/players") + { + Talo.OnConnectionRestored += OnConnectionRestored; + } + + private async void OnConnectionRestored() + { + await Talo.Socket.ResetConnection(); + + if (Talo.HasIdentity()) + { + var socketToken = await CreateSocketToken(); + if (!string.IsNullOrEmpty(socketToken)) + { + Talo.Socket.SetSocketToken(socketToken); + } + } + } public void InvokeIdentifiedEvent() { @@ -202,5 +219,24 @@ public async Task Search(string query) var res = JsonUtility.FromJson(json); return res; } + + public async Task CreateSocketToken() + { + Talo.IdentityCheck(); + + var uri = new Uri($"{baseUrl}/socket-token"); + + try + { + var json = await Call(uri, "POST"); + var res = JsonUtility.FromJson(json); + return res.socketToken; + } + catch (Exception ex) + { + Debug.LogWarning($"Failed to create socket token: {ex.Message}"); + return ""; + } + } } } diff --git a/Assets/Talo Game Services/Talo/Runtime/Responses/PlayersSocketTokenResponse.cs b/Assets/Talo Game Services/Talo/Runtime/Responses/PlayersSocketTokenResponse.cs new file mode 100644 index 0000000..6d783f9 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Runtime/Responses/PlayersSocketTokenResponse.cs @@ -0,0 +1,8 @@ +namespace TaloGameServices +{ + [System.Serializable] + public class PlayersSocketTokenResponse + { + public string socketToken; + } +} diff --git a/Assets/Talo Game Services/Talo/Runtime/Responses/PlayersSocketTokenResponse.cs.meta b/Assets/Talo Game Services/Talo/Runtime/Responses/PlayersSocketTokenResponse.cs.meta new file mode 100644 index 0000000..c5e5f57 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Runtime/Responses/PlayersSocketTokenResponse.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c327f6f5ae8f0436db0002443a489a14 \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Runtime/Talo.cs b/Assets/Talo Game Services/Talo/Runtime/Talo.cs index 67280f8..0af2359 100644 --- a/Assets/Talo Game Services/Talo/Runtime/Talo.cs +++ b/Assets/Talo Game Services/Talo/Runtime/Talo.cs @@ -7,10 +7,23 @@ namespace TaloGameServices { public class Talo { + public static event Action OnConnectionLost; + public static event Action OnConnectionRestored; + private static bool _testMode; internal static bool TestMode => _testMode; + internal static void InvokeConnectionLost() + { + OnConnectionLost?.Invoke(); + } + + internal static void InvokeConnectionRestored() + { + OnConnectionRestored?.Invoke(); + } + internal static EventsAPI _events; internal static PlayersAPI _players; internal static LeaderboardsAPI _leaderboards; @@ -218,5 +231,15 @@ internal static bool CheckTestMode() _testMode = false; return _testMode; } + + internal static void HandleConnectionLost() + { + OnConnectionLost?.Invoke(); + } + + internal static void HandleConnectionRestored() + { + OnConnectionRestored?.Invoke(); + } } } diff --git a/Assets/Talo Game Services/Talo/Runtime/TaloSocket.cs b/Assets/Talo Game Services/Talo/Runtime/TaloSocket.cs index b784ede..f960f57 100644 --- a/Assets/Talo Game Services/Talo/Runtime/TaloSocket.cs +++ b/Assets/Talo Game Services/Talo/Runtime/TaloSocket.cs @@ -130,11 +130,6 @@ public void SetSocketToken(string token) public async Task ResetConnection() { - if (!identified) - { - return; - } - CloseConnection(); socketAuthenticated = false; identified = false; diff --git a/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs b/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs index 4d6434a..9b0e644 100644 --- a/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs +++ b/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.IO; +using System.Threading.Tasks; using UnityEngine; +using UnityEngine.Networking; namespace TaloGameServices { @@ -122,5 +124,33 @@ public void ClearRequests() _requests.Clear(); WriteRequests(); } + + public async Task HandlePostResponseHealthCheck(string url, UnityWebRequest.Result result) + { + if (url.Contains("/health-check")) + { + return; + } + + var isConnectionError = result == UnityWebRequest.Result.ConnectionError; + var isDataProcessingError = result == UnityWebRequest.Result.DataProcessingError; + + if (result == UnityWebRequest.Result.Success) + { + // if offline mode is enabled, check if it shouldn't be + if (Talo.HealthCheck.GetLastStatus() == HealthCheckStatus.FAILED) + { + await Talo.HealthCheck.Ping(); + } + } + else if (isConnectionError || isDataProcessingError) + { + // if offline mode isn't enabled, check if it should be + if (Talo.HealthCheck.GetLastStatus() != HealthCheckStatus.FAILED) + { + await Talo.HealthCheck.Ping(); + } + } + } } }