1

我必须在 Web 应用程序中流式传输网络摄像机。通常我通过将 url 添加到 img 标签来做到这一点。这次的问题是请求需要摘要认证。因此,我想创建一个代理方法来处理身份验证并将数据流式传输回客户端。我目前正在尝试使用 HttpHandler 来执行此操作。

using System;
using System.Net;
using System.Web;

public class HelloWorldHandler : IHttpHandler
{
    #region IHttpHandler Members

    private const int BUFFERSIZE = 1048576;

    public bool IsReusable
    {
        get { return false; }
    }

    public void ProcessRequest(HttpContext context)
    {
        HttpWebRequest webRequest = null;

        #region Prepare the request object
        webRequest = (HttpWebRequest)WebRequest.Create("http://url/cgi/image.php?type=live");
        webRequest.Method = "GET";
        webRequest.ContentType = "multipart/x-mixed-replace; boundary=------MJPEG FAME--------";
        webRequest.Credentials = new NetworkCredential(username, password);
        #endregion Prepare the request object

        #region Cycle through and return output
        HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

        // GETS STUCK HEAR FOR OBVIOUS REASONS.  NOT SURE HOW TO BUFFER A CHUNK, STREAM THE CHUNK AND REPEAT
        System.IO.Stream fileStream = webResponse.GetResponseStream();

        Byte[] buffer = new byte[1048576];
        int bytesRead = 1;
        context.Response.ContentType = "image/png";
        while (bytesRead > 0)
        {
            bytesRead = fileStream.Read(buffer, 0, BUFFERSIZE);
            if (bytesRead == BUFFERSIZE)
                context.Response.OutputStream.Write(buffer, 0, buffer.Length);
            else if (bytesRead > 0)
            {
                byte[] endBuffer = new byte[bytesRead];
                Array.Copy(buffer, endBuffer, bytesRead);
                context.Response.OutputStream.Write(endBuffer, 0, endBuffer.Length);
            }
        }

        fileStream.Dispose();
        webResponse.Close();
        #endregion Cycle through and return output
    }

    #endregion
}

如果您查看我在代码中的注释,我已经标记了代码失败的明显位置。当我得到响应流时,它永远不会结束,直到抛出内存异常。这似乎很明显,但我不确定如何实际处理缓冲区问题。我想我需要能够缓冲一个块,流式传输,缓冲花药并重复。

作为参考,这是我通过浏览器进行直接连接时的标头示例。

要求

GET http://url/cgi/image.php?type=live HTTP/1.1
Host: url
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Authorization: Digest something something something

回复

HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Content-type: multipart/x-mixed-replace; boundary=------MJPEG FAME--------
Transfer-Encoding: chunked
Date: Mon, 04 Nov 2013 23:39:22 GMT
Server: lighttpd/1.4.28

任何建议将不胜感激。

谢谢,

乍得

4

1 回答 1

0

正如@Aristos 提到的,关键是设置 context.Repsonse.Flush()。虽然这部分问题已经解决,但我现在遇到了另一个问题。

我已经打开了另一个针对该问题的线程。https://stackoverflow.com/questions/19849148/is-it-possible-to-close-an-httpcontext-object-that-is-inside-an-httphandler-from

谢谢,

乍得

于 2013-11-07T23:55:45.627 回答