diff --git a/Assets/graphQl-client/Scripts/Core/HttpHandler.cs b/Assets/graphQl-client/Scripts/Core/HttpHandler.cs index d468af8..e35a62f 100644 --- a/Assets/graphQl-client/Scripts/Core/HttpHandler.cs +++ b/Assets/graphQl-client/Scripts/Core/HttpHandler.cs @@ -11,70 +11,117 @@ namespace GraphQlClient.Core { - public class HttpHandler - { - - - public static async Task PostAsync(string url, string details, string authToken = null){ - string jsonData = JsonConvert.SerializeObject(new{query = details}); + public class HttpHandler + { + public static async Task PostAsync( + string url, + string details, + string authToken = null + ) + { + UnityWebRequest request = UnityWebRequest.PostWwwForm( + url, + UnityWebRequest.kHttpVerbPOST + ); + + if (!string.IsNullOrEmpty(authToken)) + { + request.SetRequestHeader("Authorization", authToken); + } + + return await SendRequestAsync(request, details); + } + + public static async Task PostAsync(UnityWebRequest request, string details) + { + return await SendRequestAsync(request, details); + } + + private static async Task SendRequestAsync( + UnityWebRequest request, + string details + ) + { + string jsonData = JsonConvert.SerializeObject(new { query = details }); byte[] postData = Encoding.ASCII.GetBytes(jsonData); - UnityWebRequest request = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); request.uploadHandler = new UploadHandlerRaw(postData); request.SetRequestHeader("Content-Type", "application/json"); - if (!String.IsNullOrEmpty(authToken)) + + FireEvent(new OnRequestBegin()); + + try + { + var operation = request.SendWebRequest(); + + while (!operation.isDone) + { + await Task.Yield(); + } + + if ( + request.result == UnityWebRequest.Result.ConnectionError + || request.result == UnityWebRequest.Result.ProtocolError + ) + { + FireEvent(new OnRequestEnded(new Exception(request.error))); + } + else + { + FireEvent(new OnRequestEnded(request.downloadHandler.text)); + } + } + catch (Exception e) + { + FireEvent(new OnRequestEnded(e)); + } + + return request; + } + + private static void FireEvent(T eventData) + where T : class + { + var fireEventMethod = typeof(T).GetMethod("FireEvent"); + fireEventMethod?.Invoke(eventData, null); + } + + public static async Task GetAsync(string url, string authToken = null) + { + UnityWebRequest request = UnityWebRequest.Get(url); + if (!String.IsNullOrEmpty(authToken)) request.SetRequestHeader("Authorization", "Bearer " + authToken); - - OnRequestBegin requestBegin = new OnRequestBegin(); + OnRequestBegin requestBegin = new OnRequestBegin(); requestBegin.FireEvent(); - - try{ - await request.SendWebRequest(); + try + { + request.SendWebRequest(); + await Task.Delay(10000); } - catch(Exception e){ + catch (Exception e) + { Debug.Log("Testing exceptions"); - OnRequestEnded requestFailed = new OnRequestEnded(e); - requestFailed.FireEvent(); + OnRequestEnded requestEnded = new OnRequestEnded(e); + requestEnded.FireEvent(); } - Debug.Log(request.downloadHandler.text); - + Debug.Log(request.downloadHandler.text); OnRequestEnded requestSucceeded = new OnRequestEnded(request.downloadHandler.text); requestSucceeded.FireEvent(); return request; } - - public static async Task PostAsync(UnityWebRequest request, string details){ - string jsonData = JsonConvert.SerializeObject(new{query = details}); - byte[] postData = Encoding.ASCII.GetBytes(jsonData); - request.uploadHandler = new UploadHandlerRaw(postData); - OnRequestBegin requestBegin = new OnRequestBegin(); - requestBegin.FireEvent(); - - try{ - await request.SendWebRequest(); - } - catch(Exception e){ - Debug.Log("Testing exceptions"); - OnRequestEnded requestFailed = new OnRequestEnded(e); - requestFailed.FireEvent(); - } - Debug.Log(request.downloadHandler.text); - - OnRequestEnded requestSucceeded = new OnRequestEnded(request.downloadHandler.text); - requestSucceeded.FireEvent(); - return request; - } - - - public static async Task GetAsync(string url, string authToken = null){ + + public static async Task GetAsync(string url, string authToken = null) + { UnityWebRequest request = UnityWebRequest.Get(url); - if (!String.IsNullOrEmpty(authToken)) + if (!String.IsNullOrEmpty(authToken)) request.SetRequestHeader("Authorization", "Bearer " + authToken); - OnRequestBegin requestBegin = new OnRequestBegin(); + OnRequestBegin requestBegin = new OnRequestBegin(); requestBegin.FireEvent(); - try{ + try + { await request.SendWebRequest(); } - catch(Exception e){ + catch (Exception e) + { Debug.Log("Testing exceptions"); OnRequestEnded requestEnded = new OnRequestEnded(e); requestEnded.FireEvent(); @@ -84,143 +131,182 @@ public static async Task GetAsync(string url, string authToken requestSucceeded.FireEvent(); return request; } - + #region Websocket //Use this to subscribe to a graphql endpoint - public static async Task WebsocketConnect(string subscriptionUrl, string details, string authToken = null, string socketId = "1", string protocol = "graphql-ws"){ - string subUrl = subscriptionUrl.Replace("http", "ws"); - string id = socketId; - ClientWebSocket cws = new ClientWebSocket(); - cws.Options.AddSubProtocol(protocol); - if (!String.IsNullOrEmpty(authToken)) - cws.Options.SetRequestHeader("Authorization", "Bearer " + authToken); - Uri u = new Uri(subUrl); - try{ - await cws.ConnectAsync(u, CancellationToken.None); - if (cws.State == WebSocketState.Open) - Debug.Log("connected"); - await WebsocketInit(cws); - await WebsocketSend(cws, id, details); - } - catch (Exception e){ - Debug.Log("woe " + e.Message); - } - - return cws; - } - - public static async Task WebsocketConnect(ClientWebSocket cws, string subscriptionUrl, string details, string socketId = "1"){ - string subUrl = subscriptionUrl.Replace("http", "ws"); - string id = socketId; - Uri u = new Uri(subUrl); - try{ - await cws.ConnectAsync(u, CancellationToken.None); - if (cws.State == WebSocketState.Open) - Debug.Log("connected"); - await WebsocketInit(cws); - await WebsocketSend(cws, id, details); - } - catch (Exception e){ - Debug.Log("woe " + e.Message); - } - - return cws; - } - - static async Task WebsocketInit(ClientWebSocket cws){ - string jsonData = "{\"type\":\"connection_init\"}"; - ArraySegment b = new ArraySegment(Encoding.ASCII.GetBytes(jsonData)); - await cws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None); - GetWsReturn(cws); - } - - static async Task WebsocketSend(ClientWebSocket cws, string id, string details){ - string jsonData = JsonConvert.SerializeObject(new {id = $"{id}", type = "start", payload = new{query = details}}); - ArraySegment b = new ArraySegment(Encoding.ASCII.GetBytes(jsonData)); - await cws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None); - } - - //Call GetWsReturn to wait for a message from a websocket. GetWsReturn has to be called for each message - static async void GetWsReturn(ClientWebSocket cws){ - ArraySegment buf = new ArraySegment(new byte[1024]); - buf = WebSocket.CreateClientBuffer(1024, 1024); - WebSocketReceiveResult r; - string result = ""; - do{ - r = await cws.ReceiveAsync(buf, CancellationToken.None); - result += Encoding.UTF8.GetString(buf.Array ?? throw new ApplicationException("Buf = null"), buf.Offset, - r.Count); - } while (!r.EndOfMessage); - - if (String.IsNullOrEmpty(result)) - return; - JObject obj = new JObject(); - try{ - obj = JObject.Parse(result); - } - catch (JsonReaderException e){ - throw new ApplicationException(e.Message); - } - - string subType = (string) obj["type"]; - switch (subType){ - case "connection_ack": - { - Debug.Log("init_success, the handshake is complete"); - OnSubscriptionHandshakeComplete subscriptionHandshakeComplete = - new OnSubscriptionHandshakeComplete(); - subscriptionHandshakeComplete.FireEvent(); - GetWsReturn(cws); - break; - } - case "error": - { - throw new ApplicationException("The handshake failed. Error: " + result); - } - case "connection_error": - { - throw new ApplicationException("The handshake failed. Error: " + result); - } - case "data": - { - OnSubscriptionDataReceived subscriptionDataReceived = new OnSubscriptionDataReceived(result); - subscriptionDataReceived.FireEvent(); - GetWsReturn(cws); - break; - } - case "ka": - { - GetWsReturn(cws); - break; - } - case "subscription_fail": - { - throw new ApplicationException("The subscription data failed"); - } - - } - } - - public static async Task WebsocketDisconnect(ClientWebSocket cws, string socketId = "1"){ - string jsonData = $"{{\"type\":\"stop\",\"id\":\"{socketId}\"}}"; - ArraySegment b = new ArraySegment(Encoding.ASCII.GetBytes(jsonData)); - await cws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None); - await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed", CancellationToken.None); - OnSubscriptionCanceled subscriptionCanceled = new OnSubscriptionCanceled(); - subscriptionCanceled.FireEvent(); - } - - #endregion - - #region Utility - - public static string FormatJson(string json) + public static async Task WebsocketConnect( + string subscriptionUrl, + string details, + string authToken = null, + string socketId = "1", + string protocol = "graphql-ws" + ) + { + string subUrl = subscriptionUrl.Replace("http", "ws"); + string id = socketId; + ClientWebSocket cws = new ClientWebSocket(); + cws.Options.AddSubProtocol(protocol); + if (!String.IsNullOrEmpty(authToken)) + cws.Options.SetRequestHeader("Authorization", "Bearer " + authToken); + Uri u = new Uri(subUrl); + try + { + await cws.ConnectAsync(u, CancellationToken.None); + if (cws.State == WebSocketState.Open) + Debug.Log("connected"); + await WebsocketInit(cws); + await WebsocketSend(cws, id, details); + } + catch (Exception e) + { + Debug.Log("woe " + e.Message); + } + + return cws; + } + + public static async Task WebsocketConnect( + ClientWebSocket cws, + string subscriptionUrl, + string details, + string socketId = "1" + ) + { + string subUrl = subscriptionUrl.Replace("http", "ws"); + string id = socketId; + Uri u = new Uri(subUrl); + try + { + await cws.ConnectAsync(u, CancellationToken.None); + if (cws.State == WebSocketState.Open) + Debug.Log("connected"); + await WebsocketInit(cws); + await WebsocketSend(cws, id, details); + } + catch (Exception e) + { + Debug.Log("woe " + e.Message); + } + + return cws; + } + + static async Task WebsocketInit(ClientWebSocket cws) + { + string jsonData = "{\"type\":\"connection_init\"}"; + ArraySegment b = new ArraySegment(Encoding.ASCII.GetBytes(jsonData)); + await cws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None); + GetWsReturn(cws); + } + + static async Task WebsocketSend(ClientWebSocket cws, string id, string details) + { + string jsonData = JsonConvert.SerializeObject( + new + { + id = $"{id}", + type = "start", + payload = new { query = details } + } + ); + ArraySegment b = new ArraySegment(Encoding.ASCII.GetBytes(jsonData)); + await cws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None); + } + + //Call GetWsReturn to wait for a message from a websocket. GetWsReturn has to be called for each message + static async void GetWsReturn(ClientWebSocket cws) + { + ArraySegment buf = new ArraySegment(new byte[1024]); + buf = WebSocket.CreateClientBuffer(1024, 1024); + WebSocketReceiveResult r; + string result = ""; + do + { + r = await cws.ReceiveAsync(buf, CancellationToken.None); + result += Encoding.UTF8.GetString( + buf.Array ?? throw new ApplicationException("Buf = null"), + buf.Offset, + r.Count + ); + } while (!r.EndOfMessage); + + if (String.IsNullOrEmpty(result)) + return; + JObject obj = new JObject(); + try + { + obj = JObject.Parse(result); + } + catch (JsonReaderException e) + { + throw new ApplicationException(e.Message); + } + + string subType = (string)obj["type"]; + switch (subType) + { + case "connection_ack": + { + Debug.Log("init_success, the handshake is complete"); + OnSubscriptionHandshakeComplete subscriptionHandshakeComplete = + new OnSubscriptionHandshakeComplete(); + subscriptionHandshakeComplete.FireEvent(); + GetWsReturn(cws); + break; + } + case "error": + { + throw new ApplicationException("The handshake failed. Error: " + result); + } + case "connection_error": + { + throw new ApplicationException("The handshake failed. Error: " + result); + } + case "data": + { + OnSubscriptionDataReceived subscriptionDataReceived = + new OnSubscriptionDataReceived(result); + subscriptionDataReceived.FireEvent(); + GetWsReturn(cws); + break; + } + case "ka": + { + GetWsReturn(cws); + break; + } + case "subscription_fail": + { + throw new ApplicationException("The subscription data failed"); + } + } + } + + public static async Task WebsocketDisconnect(ClientWebSocket cws, string socketId = "1") + { + string jsonData = $"{{\"type\":\"stop\",\"id\":\"{socketId}\"}}"; + ArraySegment b = new ArraySegment(Encoding.ASCII.GetBytes(jsonData)); + await cws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None); + await cws.CloseAsync( + WebSocketCloseStatus.NormalClosure, + "Closed", + CancellationToken.None + ); + OnSubscriptionCanceled subscriptionCanceled = new OnSubscriptionCanceled(); + subscriptionCanceled.FireEvent(); + } + + #endregion + + #region Utility + + public static string FormatJson(string json) { var parsedJson = JsonConvert.DeserializeObject(json); return JsonConvert.SerializeObject(parsedJson, Formatting.Indented); } - #endregion - } + #endregion + } }