1

我们有一个客户端应用程序,允许用户下载全长 192Kb/s MP3 音频文件。因为文件作为企业存储在我们外部,所以我们需要能够:

1)将文件从外部位置复制到本地服务器缓存中

2)将该文件复制到请求它的客户端

显然,对同一文件的进一步请求将来自缓存,并且不需要转到外部。

现在,我们已经有一个执行此操作的当前系统(使用 Squid 缓存),但问题是 2 仅在 1 完全完成后执行。这意味着,如果一个 10 分钟长的 192kb/s 曲目需要 75 秒从外部位置复制到缓存中,则客户端的 HTTP 超时时间大约为 60 秒!这不符合我们的要求。

似乎我们需要的是一个可以在客户端从外部位置获取数据时传输到客户端的缓存。我的问题是:

1) 这可以用 Squid Cache 来完成吗(这是传统的现任者,而不是我的选择)?

2)如果不是,哪种技术最适合这种情况(成本不是真正的问题)?

如果有任何不清楚的地方,请告诉我!

4

1 回答 1

1

这是我不久前写的一个 asp.net 处理程序,用于代理来自另一台服务器的一些内容。写入文件并第二次使用该文件并不难。在循环中刷新响应将使其在下载时交付:

namespace bla.com
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Proxy : IHttpHandler
    {
        private static Regex urlRegex=new Regex(@"http://some_regex_here_to_prevent_abuse_of_proxy.mp3",RegexOptions.Compiled);
        public void ProcessRequest(HttpContext context)
        {
            var targetUrl = context.Request.QueryString["url"];
            MatchCollection matches = urlRegex.Matches(targetUrl);

            if (matches.Count != 1 || matches[0].Value != targetUrl)
            {
                context.Response.StatusCode = 403;
                context.Response.ContentType = "text/plain";
                context.Response.Write("Forbidden");
                return;
            }

            HttpWebRequest req = (HttpWebRequest) WebRequest.Create(targetUrl);
            Stream responseStream;
            using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
            {
                responseStream = response.GetResponseStream();
                context.Response.ContentType = response.ContentType;

                byte[] buffer = new byte[4096];
                int amt;
                while ((amt = responseStream.Read(buffer, 0, 4096))>0)
                {

                    context.Response.OutputStream.Write(buffer, 0, amt);
                    Debug.WriteLine(amt);
                } 
                responseStream.Close();
                response.Close();
            }
            context.Response.Flush();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
于 2009-04-10T12:21:12.190 回答