我尝试制作一个简单的代理服务器,尝试从IP摄像机流回数据(IP摄像机不支持OPTIONS,还有一些其他问题!)。我尝试使用NancyFX和Krestrel使用以下代理模块执行此操作。我们的想法是获取1028个字节的数据并将其异步写入输出流,直到被取消。
以下是南希模块的示例:
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Nancy;
namespace Server.Modules
{
public class Proxy : NancyModule
{
public Proxy() : base("api/proxy")
{
Get("/", ProxyPage);
}
private async Task<Response> ProxyPage(dynamic args, CancellationToken cancellationToken)
{
// Create HttpClient
using (var httpClient = new HttpClient()) // Make this global/cached and indexed by auth code
{
// Handle Authentication
var auth = string.Empty;
if (!string.IsNullOrEmpty(Request.Headers.Authorization) && Request.Headers.Authorization.Contains(" "))
auth = Request.Headers.Authorization.Split(' ')[1];
else if (!string.IsNullOrEmpty(Request.Query.authorization))
auth = Request.Query.authorization;
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth);
// Create Proxy REsponse object
var proxyResponse = new Response();
// Get Async
HttpResponseMessage response = await httpClient.GetAsync(Request.Query["url"],
HttpCompletionOption.ResponseHeadersRead, cancellationToken);
// Set Content Type
proxyResponse.ContentType = response.Content.Headers.ContentType.ToString();
// Set Status Code
proxyResponse.StatusCode = (HttpStatusCode)(int)response.StatusCode;
// Handle stream writing
proxyResponse.Contents = async s =>
{
var result = response.Content.ReadAsStreamAsync();
var data = new byte[1028];
int bytesRead;
while (!cancellationToken.IsCancellationRequested && (bytesRead = await result.Result.ReadAsync(data, 0, data.Length, cancellationToken)) > 0)
{
await s.WriteAsync(data, 0, bytesRead, cancellationToken);
await s.FlushAsync(cancellationToken);
}
response.Dispose();
};
// Return Response container
return proxyResponse;
}
}
}
}
当我运行它时,我经历了几次while循环,但在FrameResponseStream(Krestrel)中得到一个异常:&#34; System.ObjectDisposedException:&#39;无法访问已处置的对象。&#39; &#34;看来流已经过早关闭(_state = FrameStreamState.Closed - https://github.com/aspnet/KestrelHttpServer/blob/rel/2.0.0/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameResponseStream.cs),但我无法弄清楚为什么或需要改变它来解决它!
答案 0 :(得分:0)
您应该使用ResponseContentRead而不是ResponseHeadersRead
HttpResponseMessage response = await httpClient.GetAsync(Request.Query["url"],
HttpCompletionOption.ResponseContentRead, cancellationToken);