我正在尝试将一些数据上传到网络服务。
我想上传数据in chunks,让网络服务依次读取每个块。但是,我在实践中发现,Web服务一次只能读取一个完整的缓冲区。
有没有办法获得WebAPI(理想情况下由Owin自行运行,但如果需要,我可以使用IIS)来尊重传输块?
我在Wireshark中验证过我的客户端正在发送数据块,因此我认为这是一个WebAPI问题。
为清楚起见,响应中的流数据非常正常 - 我的问题是从请求流中读取分块数据。
控制器如下所示:
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
public class StreamingController : ApiController
{
[HttpPost]
public async Task<HttpResponseMessage> Upload()
{
var stream = await this.Request.Content.ReadAsStreamAsync();
var data = new byte[20];
int chunkCount = 1;
while (true)
{
// I was hoping that every time I sent a chunk, then
// ReadAsync would return, but I find that it will only
// return when I have sent 20 bytes of data.
var bytesRead = await stream.ReadAsync(data, 0, data.Length);
if (bytesRead <= 0)
{
break;
}
Console.WriteLine($"{chunkCount++}: {Encoding.UTF8.GetString(data)}");
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
我的测试客户端看起来像这样:
void Main()
{
var url = "http://localhost:6001/streaming/upload";
var relayRequest = (HttpWebRequest)HttpWebRequest.Create(url);
relayRequest.Method = "POST";
relayRequest.AllowWriteStreamBuffering = false;
relayRequest.AllowReadStreamBuffering = false;
relayRequest.SendChunked = true;
relayRequest.ContentType = "application/octet-stream";
var stream = relayRequest.GetRequestStream();
string nextLine;
int totalBytes = 0;
// Read a series of lines from the console and transmit them to the server.
while(!string.IsNullOrEmpty((nextLine = Console.ReadLine())))
{
var bytes = Encoding.UTF8.GetBytes(nextLine);
totalBytes += bytes.Length;
Console.WriteLine(
"CLIENT: Sending {0} bytes ({1} total)",
bytes.Length,
totalBytes);
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
}
var response = relayRequest.GetResponse();
Console.WriteLine(response);
}
我的具体动机是我正在为RTP客户端编写HTTPS隧道。但是,这个问题在即时消息聊天应用程序的上下文中也是有意义的。您不希望部分聊天消息通过,然后必须等待消息2才能找到消息1的结尾......!
答案 0 :(得分:2)
Transfer-Encoding: chunked
的解码远离您的控制器。根据您的主机,它可能根本不会在应用程序中发生,而是由大多数服务器插入的http.sys
pipeline API处理。
为了使您的应用程序能够查看此数据,您需要远离IIS / HttpListener并使用套接字。
感兴趣的可能是Nowin project,它提供了所有OWIN功能而不使用HttpListener,而是依赖于Socket异步API。我对此并不了解,但 可能 可以在解码之前获取流,但这似乎很费劲。