示例#1
0
        // Safely handles
        private bool ProcessStringResponse(string stringResponse)
        {
            // Decode full response
            responseData = WitResponseJson.Parse(stringResponse);

            // Handle responses
            bool isFinal = responseData.HandleResponse((transcription, final) =>
            {
                // Call partial transcription
                if (!final)
                {
                    MainThreadCallback(() => onPartialTranscription?.Invoke(transcription));
                }
                // Call full transcription
                else
                {
                    MainThreadCallback(() => onFullTranscription?.Invoke(transcription));
                }
            }, (response, final) =>
            {
                // Call partial response
                SafeInvoke(onPartialResponse);
                // Call final response
                if (final)
                {
                    SafeInvoke(onResponse);
                }
            });

            // Return final
            return(isFinal);
        }
示例#2
0
        private void HandleResponse(IAsyncResult ar)
        {
            bool   sentResponse   = false;
            string stringResponse = "";

            responseStarted = true;
            try
            {
                response = (HttpWebResponse)_request.EndGetResponse(ar);

                statusCode        = (int)response.StatusCode;
                statusDescription = response.StatusDescription;

                try
                {
                    var responseStream = response.GetResponseStream();
                    if (response.Headers["Transfer-Encoding"] == "chunked")
                    {
                        byte[] buffer    = new byte[10240];
                        int    bytes     = 0;
                        int    offset    = 0;
                        int    totalRead = 0;
                        while ((bytes = responseStream.Read(buffer, offset, buffer.Length - offset)) > 0)
                        {
                            totalRead     += bytes;
                            stringResponse = Encoding.UTF8.GetString(buffer, 0, totalRead);
                            if (stringResponse.EndsWith("\r\n"))
                            {
                                try
                                {
                                    offset        = 0;
                                    totalRead     = 0;
                                    sentResponse |= ProcessStringResponse(stringResponse);
                                }
                                catch (JSONParseException e)
                                {
                                    offset = bytes;
                                    Debug.LogWarning("Received what appears to be a partial response or invalid json. Attempting to continue reading. Parsing error: " + e.Message + "\n" + stringResponse);
                                }
                            }
                            else
                            {
                                offset = totalRead;
                            }
                        }

                        // If the final transmission didn't end with \r\n process it as the final
                        // result
                        if (!stringResponse.EndsWith("\r\n") && !string.IsNullOrEmpty(stringResponse))
                        {
                            sentResponse |= ProcessStringResponse(stringResponse);
                        }

                        if (stringResponse.Length > 0 && null != responseData)
                        {
                            MainThreadCallback(() => onRawResponse?.Invoke(stringResponse));
                        }
                    }
                    else
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            stringResponse = reader.ReadToEnd();
                            MainThreadCallback(() => onRawResponse?.Invoke(stringResponse));
                            responseData = WitResponseJson.Parse(stringResponse);
                        }
                    }

                    responseStream.Close();
                }
                catch (JSONParseException e)
                {
                    Debug.LogError("Server returned invalid data: " + e.Message + "\n" +
                                   stringResponse);
                    statusCode        = ERROR_CODE_INVALID_DATA_FROM_SERVER;
                    statusDescription = "Server returned invalid data.";
                }
                catch (Exception e)
                {
                    Debug.LogError(
                        $"{e.Message}\nRequest Stack Trace:\n{callingStackTrace}\nResponse Stack Trace:\n{e.StackTrace}");
                    statusCode        = ERROR_CODE_GENERAL;
                    statusDescription = e.Message;
                }

                response.Close();
            }
            catch (WebException e)
            {
                statusCode = (int)e.Status;
                if (e.Response is HttpWebResponse errorResponse)
                {
                    statusCode = (int)errorResponse.StatusCode;

                    try
                    {
                        var stream = errorResponse.GetResponseStream();
                        if (null != stream)
                        {
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                stringResponse = reader.ReadToEnd();
                                MainThreadCallback(() => onRawResponse?.Invoke(stringResponse));
                                responseData = WitResponseJson.Parse(stringResponse);
                            }
                        }
                    }
                    catch (JSONParseException)
                    {
                        // Response wasn't encoded error, ignore it.
                    }
                    catch (Exception errorResponseError)
                    {
                        // We've already caught that there is an error, we'll ignore any errors
                        // reading error response data and use the status/original error for validation
                        Debug.LogWarning(errorResponseError);
                    }
                }

                statusDescription = e.Message;
                if (e.Status != WebExceptionStatus.RequestCanceled)
                {
                    Debug.LogError(
                        $"Http Request Failed [{statusCode}]: {e.Message}\nRequest Stack Trace:\n{callingStackTrace}\nResponse Stack Trace:\n{e.StackTrace}");
                }
            }
            finally
            {
                isActive = false;
            }

            CloseRequestStream();

            if (null != responseData)
            {
                var error = responseData["error"];
                if (!string.IsNullOrEmpty(error))
                {
                    statusDescription = $"Error: {responseData["code"]}. {error}";
                    statusCode        = statusCode == 200 ? ERROR_CODE_GENERAL : statusCode;
                }
            }
            else if (statusCode == 200)
            {
                statusCode        = ERROR_CODE_NO_DATA_FROM_SERVER;
                statusDescription = "Server did not return a valid json response.";
                Debug.LogWarning(
                    "No valid data was received from the server even though the request was successful. Actual potential response data: \n" +
                    stringResponse);
            }

            // Send final response if have not yet
            if (!sentResponse)
            {
                // Final transcription
                string transcription = responseData.GetTranscription();
                if (!string.IsNullOrEmpty(transcription))
                {
                    MainThreadCallback(() => onFullTranscription?.Invoke(transcription));
                }
                // Final response
                SafeInvoke(onResponse);
            }

            // Complete
            responseStarted = false;
        }
示例#3
0
        private void HandleResponse(IAsyncResult ar)
        {
            string stringResponse = "";

            responseStarted = true;
            try
            {
                response = (HttpWebResponse)request.EndGetResponse(ar);

                statusCode        = (int)response.StatusCode;
                statusDescription = response.StatusDescription;

                try
                {
                    var responseStream = response.GetResponseStream();
                    if (response.Headers["Transfer-Encoding"] == "chunked")
                    {
                        byte[] buffer    = new byte[10240];
                        int    bytes     = 0;
                        int    offset    = 0;
                        int    totalRead = 0;
                        while ((bytes = responseStream.Read(buffer, offset, buffer.Length - offset)) > 0)
                        {
                            totalRead     += bytes;
                            stringResponse = Encoding.UTF8.GetString(buffer, 0, totalRead);
                            if (stringResponse.Length > 0)
                            {
                                try
                                {
                                    responseData = WitResponseJson.Parse(stringResponse);

                                    offset = 0;

                                    totalRead = 0;
                                    if (null != responseData)
                                    {
                                        var transcription = responseData["text"];
                                        if (!string.IsNullOrEmpty(transcription))
                                        {
                                            onPartialTranscription?.Invoke(transcription);
                                        }
                                    }
                                }
                                catch (JSONParseException e)
                                {
                                    // TODO: t105419819 Update the protocol to better handle this issue.
                                    // This is a bit of a hack to get around an issue with a full
                                    // socket buffer or partial server response. We will need to
                                    // address this server side to make sure we're reading all data
                                    // rather than relying on a json parse exception to catch this.
                                    // Test case: Utterance with multiple entity responses pushing
                                    // final data > 1024 bytes.
                                    offset = bytes;
                                    Debug.LogWarning("Received what appears to be a partial response or invalid json. Attempting to continue reading. Parsing error: " + e.Message);
                                }
                            }
                        }

                        if (stringResponse.Length > 0 && null != responseData)
                        {
                            onFullTranscription?.Invoke(responseData["text"]);
                            onRawResponse?.Invoke(stringResponse);
                        }
                    }
                    else
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            stringResponse = reader.ReadToEnd();
                            onRawResponse?.Invoke(stringResponse);
                            responseData = WitResponseJson.Parse(stringResponse);
                        }
                    }

                    responseStream.Close();
                }
                catch (JSONParseException e)
                {
                    Debug.LogError("Server returned invalid data: " + e.Message + "\n" +
                                   stringResponse);
                    statusCode        = ERROR_CODE_INVALID_DATA_FROM_SERVER;
                    statusDescription = "Server returned invalid data.";
                }
                catch (Exception e)
                {
                    Debug.LogError(
                        $"{e.Message}\nRequest Stack Trace:\n{callingStackTrace}\nResponse Stack Trace:\n{e.StackTrace}");
                    statusCode        = ERROR_CODE_GENERAL;
                    statusDescription = e.Message;
                }

                response.Close();
            }
            catch (WebException e)
            {
                statusCode = (int)e.Status;
                if (e.Response is HttpWebResponse errorResponse)
                {
                    statusCode = (int)errorResponse.StatusCode;

                    try
                    {
                        var stream = errorResponse.GetResponseStream();
                        if (null != stream)
                        {
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                stringResponse = reader.ReadToEnd();
                                onRawResponse?.Invoke(stringResponse);
                                responseData = WitResponseJson.Parse(stringResponse);
                            }
                        }
                    }
                    catch (JSONParseException)
                    {
                        // Response wasn't encoded error, ignore it.
                    }
                    catch (Exception errorResponseError)
                    {
                        // We've already caught that there is an error, we'll ignore any errors
                        // reading error response data and use the status/original error for validation
                        Debug.LogWarning(errorResponseError);
                    }
                }

                statusDescription = e.Message;
                if (e.Status != WebExceptionStatus.RequestCanceled)
                {
                    Debug.LogError(
                        $"Http Request Failed [{statusCode}]: {e.Message}\nRequest Stack Trace:\n{callingStackTrace}\nResponse Stack Trace:\n{e.StackTrace}");
                }
            }
            finally
            {
                isActive = false;
            }

            CloseRequestStream();

            if (null != responseData)
            {
                var error = responseData["error"];
                if (!string.IsNullOrEmpty(error))
                {
                    statusDescription = $"Error: {responseData["code"]}. {error}";
                    statusCode        = statusCode == 200 ? ERROR_CODE_GENERAL : statusCode;
                }
            }
            else if (statusCode == 200)
            {
                statusCode        = ERROR_CODE_NO_DATA_FROM_SERVER;
                statusDescription = "Server did not return a valid json response.";
                Debug.LogWarning(
                    "No valid data was received from the server even though the request was successful. Actual potential response data: \n" +
                    stringResponse);
            }

            SafeInvoke(onResponse);
        }