使用HttpClient和PushStreamContent

时间:2018-11-12 13:00:12

标签: c# rest httpclient pushstreamcontent

我需要将音频数据从麦克风传输到REST服务器。

我正在使用专有ASR引擎,需要收集数据,然后在一次调用PostAsync中实时传输数据 在网上看时,我在PushStreamContent上找到了文章,但是要么我没有正确使用它,要么我不明白我在做什么(或两者都没有)。

我有一个称为stream_memory的MemoryStream,我不断地从主线程向其中写入数据,并且我想在数据流传输时读取它,并将其实时发布在一个帖子中。在下面的示例中,我还使用事件stream_data_event和对象锁来防止多个线程同时写入MemoryStream。每次读取数据时都会清除内存流,因为以后不需要数据。

这是我的代码片段,它在自己的线程中运行:

http_client = new HttpClient();
http_client.http_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
http_client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Language", "en-us");
http_client.DefaultRequestHeaders.TransferEncodingChunked = true;
HttpContent content = new System.Net.Http.PushStreamContent(async (stream, httpContent, transportContext) =>
            {
                while (stream_data_event.WaitOne())
                {

                    lock (main_window.stream_memory_lock)
                    {
                        stream_data_event.Reset();
                        long write_position = main_window.stream_memory.Position;
                        main_window.stream_memory.Seek(0, SeekOrigin.Begin);
                        main_window.stream_memory.CopyTo(stream, (int)write_position);
                        main_window.stream_memory.Position = 0;
                    }
                }
            });
content.Headers.TryAddWithoutValidation("Content-Type", "audio/L16;rate=8000");
string request_uri = String.Format("/v1/speech:recognize");

HttpResponseMessage response = await http_client.PostAsync(request_uri, content);
string http_result = await response.Content.ReadAsStringAsync();

对PostAsync的调用按预期方式调用PushStreamContent的代码。 但是,只要我处于while循环中,什么都不会发送到服务器(在wireshark中检查)。 如果我在调试器中手动退出循环并在流上调用close,则PostAsync存在,但没有任何内容发送到服务器。

我需要一种方法在PostAsync中继续流式传输信息,并在音频到达时使数据消失。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

事实证明,未将任何内容发送到服务器的原因与Wireshark显示HTTP结果的方式有关。 我的期望是,一旦发送了请求,我将立即在Wireshark中看到它。但是,wireshark仅在请求完成后才显示请求,这意味着在请求开始流式传输之后很久才显示该请求。

意识到这一点之后,就可以将数据发送到服务器了。