HttpListener将数据写入响应输出流

3

我有一个基于HttpListener的小型本地Web服务器。该服务器向本地客户端应用程序提供文件,解压并将文件写入。

response.OutputStream;

但有时文件(视频)非常大,我认为总是将所有文件字节复制到输出流(内存)中并不是一个好主意。我想要将服务的文件流连接到响应输出流中,类似于以下方式:

response.OutputStream = myFileStream;

但是 -OK- response.OutputStream 是只读的,所以我只能写入字节 - 有没有一种方式可以进行部分写入(流式处理)?
问候。

1
所以...你正在尝试创建一个流连接,下一步将是将文件分成单独的包并同时发送它们,并在客户端重新构建它们...为什么不直接这样做呢? - No Idea For Name
已提供的视频文件将在Web浏览器(Gecko FX)中显示,并且当视频(MP4)请求到来时(HTML5 <video>标记),请求不会指定所请求的字节范围(例如缓冲),因此我不知道如何实现部分发送。 - Przemysław Michalski
1个回答

2
您需要创建一个线程并将数据流式传输到响应中。可以像这样使用:

在您的主线程中:

while (Listening)
{
    // wait for next incoming request
    var result = listener.BeginGetContext(ListenerCallback, listener);
    result.AsyncWaitHandle.WaitOne();
}

在你的类中的某个地方:

public static void ListenerCallback(IAsyncResult result)
{
    var listenerClosure = (HttpListener)result.AsyncState;
    var contextClosure = listenerClosure.EndGetContext(result);

    // do not process request on the dispatcher thread, schedule it on ThreadPool
    // otherwise you will prevent other incoming requests from being dispatched
    ThreadPool.QueueUserWorkItem(
        ctx =>
        {
            var response = (HttpListenerResponse)ctx;

            using (var stream = ... )
            {
                stream.CopyTo(response.ResponseStream);
            }

            response.Close();
        }, contextClosure.Response);
}

1
这里有一个类似的帖子(包含更多上下文信息):https://dev59.com/5GYr5IYBdhLWcg3wy9KA?rq=1 - Roman Polunin
1
我认为 stream.CopyTo(response.ResponseStream) 会将所有文件字节复制到输出流中,而这正是我想要避免的。 - Przemysław Michalski
1
UGEEN,如果您将.AllowWriteStreamBuffering属性设置为false,则不会在本地缓存任何内容。当客户端停止接收时,它将停止发送。 - Roman Polunin
1
通常情况下,如果您不希望从服务器发送所有内容,您需要期望客户端告诉您它确切地需要什么。对于视频而言,可能有特殊的约定,但对于常规数据,通常客户端会附加 'content-range' 头部,您可以期望收到客户端想要在对这个特定请求的响应中获取的字节范围。请参考这里:https://dev59.com/EHRB5IYBdhLWcg3wHkPi - Roman Polunin
1
另外,请记住,即使CopyTo会发送所有内容,它也不会尝试先将数据缓存到服务器内存中。HttpListener的响应实现也不会缓存已发送的数据。 - Roman Polunin
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接