dou*_*ald 13 c# asp.net-mvc-4 lib.web.mvc http-range
我有一个应用程序,旨在从我们的本地数据库流回视频.昨天我花了很多时间试图将数据返回成功RangeFileContentResult或RangeFileStreamResult不成功.
简而言之,当我将文件作为这两个结果中的任何一个返回时,我似乎无法正确地传输视频(或者根本不播放).
来自浏览器的请求将通过以下标头发送:
Range: bytes=0-
Run Code Online (Sandbox Code Playgroud)
并且提供的响应以这些标头为例:
Accept-Ranges: bytes
Content-Range: bytes 0-5103295/5103296
Run Code Online (Sandbox Code Playgroud)
在网络流量方面,我获得了一系列206的部分结果,然后是200结尾(根据小提琴手),这似乎是正确的.Chrome的网络标签不同意这一点,并看到一个初始请求(总是13个字节,我假设是握手)然后是一些状态为已取消或待处理的请求.据我所知,这或多或少是正确的,206 - 取消,206 - 取消等.但视频永远不会播放.
如果我将结果从我的控制器切换到FileResult,视频播放和Chrome,IE10和Firefox似乎在下载完成之前开始播放(感觉有点像它的流媒体!虽然我怀疑它不是)
但是随着范围的结果,我在chrome或IE中得不到任何东西,整个视频在firefox中下载了一滴.
据我所知,RangeFileContentResult应该处理响应客户端的一系列字节要下载(我的似乎没有,它只是告诉它获取整个文件(由上面的响应说明)).客户应该对此做出回应,而这似乎并没有.
有没有人对这方面有任何想法?特别:
a)应该RangeFileContentResult将一系列字节发送回客户端吗?b)有没有办法可以明确控制客户端请求的字节范围?c)在请求时,是否有任何理由或错误导致浏览器根本不加载视频RangeFileContentResult?
编辑:添加了一个图表,以帮助描述我所看到的:

编辑2:好的,所以情节变浓了.在使用RangedFile gubbins的同时,我们需要推出另一个系统测试版本,并将"RangeFileContentResult"留在我的控制器操作上,如下所示:
private ActionResult RetrieveVideo(MediaItem media)
{
return new RangeFileContentResult(
media.Content,
media.MimeType,
media.Id.ToString(),
DateTime.Now);
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这似乎在我们的Azure系统测试环境中按预期工作,但仍然不在我的本地计算机上.我想知道是否有一些基于IIS的东西在Azures IIS8上运行得很开心,但在我的本地7.5实例上却没有?
这里描述的问题的原因是传递给构造函数的modificationDate参数的值RangeFileContentResult:
return new RangeFileContentResult(media.Content, media.MimeType, media.Id.ToString(), DateTime.Now);
Run Code Online (Sandbox Code Playgroud)
此日期用于RangeFileResult创建两个标头:
ETag - 此标头是浏览器和服务器使用的标识符,用于确保它们正在谈论同一实体.Last-Modified - 此标头通知浏览器实体的最后修改日期.DateTime.Now每次浏览器发出部分请求时传递a的事实可能是在客户端获取整个实体之前更改ETag和Last-Modified标头值的原因(通常如果整个过程花费的时间超过一秒).
在上述情况下,浏览器正在发送If-Range带有请求的标头.如果实体标记(或修改日期因为If-Range可以携带这两个值中的任何一个)并不多,则此标头告诉服务器应重新发送整个实体.在这种情况下会发生这种情况.
事实上,修改日期是"动态的"也可引起进一步的问题,如果客户决定使用以下标题之一验证:If-Modified-Since,If-Unmodified-Since,If-Match,If-None-Match.
在这种情况下的解决方案是在数据库中保留修改日期与文件,以确保它是一致的.
这里还有一个优化的地方.每次发出部分请求时,不是从DB抓取整个视频,而是可以缓存它或仅抓取相关部分(如果应用程序正在使用的数据库引擎允许这样的操作).可以使用这种机制以通过传递RangeFileResult和覆盖WriteEntireEntity以及WriteEntityRange方法来创建专门的动作结果.
| 归档时间: |
|
| 查看次数: |
2975 次 |
| 最近记录: |