【发布时间】:2016-11-06 09:26:02
【问题描述】:
我正在使用 ASP.NET MVC 开发一个视频网站。
我想在我的应用程序中拥有一个功能是转码视频。但由于转码过程可能非常耗时,我想向客户端用户展示该过程的进度。
因此,我的架构是使用一个控制器操作来处理整个转码过程,并将其进度写入存储在服务器上的文件中。同时我使用Ajax调用另一个控制器动作来读取指定的文件,检索进度信息并在转码过程中每2秒将其发送回客户端显示。
为了完成我的计划,我编写了以下代码:
服务器端:
public class VideoController : Controller
{
//Other action methods
....
//Action method for transcoding a video given by its id
[HttpPost]
public async Task<ActionResult> Transcode(int vid=0)
{
VideoModel VideoModel = new VideoModel();
Video video = VideoModel.GetVideo(vid);
string src = Server.MapPath("~/videos/")+video.Path;
string trg = Server.MapPath("~/videos/") + +video.Id+".mp4";
//The file that stores the progress information
string logPath = Server.MapPath("~/videos/") + "transcode.txt";
string pathHeader=Server.MapPath("../");
if (await VideoModel.ConvertVideo(src.Trim(), trg.Trim(), logPath))
{
return Json(new { result = "" });
}
else
{
return Json(new { result = "Transcoding failed, please try again." });
}
}
//Action method for retrieving the progress value from the specified log file
public ActionResult GetProgress()
{
string logPath = Server.MapPath("~/videos/") + "transcode.txt";
//Retrive the progress from the specified log file.
...
return Json(new { progress = progress });
}
}
客户端:
var progressTimer = null;
var TranscodeProgress = null;
// The function that requests server for handling the transcoding process
function Transcode(vid) {
// Calls the Transcode action in VideoController
var htmlobj = $.ajax({
url: "/Video/Transcode",
type: "POST",
//dataType: 'JSON',
data: { 'vid': vid },
success: function(data)
{
if(data.result!="")
alert(data.result);
}
else
{
//finalization works
....
}
}
});
//Wait for 1 seconds to start retrieving transcoding progress
progressTimer=setTimeout(function ()
{
//Display progress bar
...
//Set up the procedure of retrieving progress every 2 seconds
TranscodeProgress = setInterval(Transcoding, 2000);
}, 1000);
}
//The function that requests the server for retrieving the progress information every 2 seconds.
function Transcoding()
{
//Calls the GetProgress action in VideoController
$.ajax({
url: "/Video/GetProgress",
type: "POST",
//dataType: 'JSON',
success: function (data)
{
if (data.progress == undefined || data.progress == null)
return;
progressPerc = parseFloat(data.progress);
//Update progress bar
...
}
});
}
现在客户端代码和Transcode 操作方法都可以正常工作。问题是在Transcode 操作完成其整个过程之前,永远不会调用GetProgress 方法。那么我的代码有什么问题?我如何修改它以使这两个动作自发地工作以实现我的目标?
更新
根据Alex的回答,我发现我的问题是由Asp.Net框架的会话锁定机制引起的。因此,禁用我的VideoController 的SessionState 或将其设置为只读确实会使控制器在执行转码视频的操作方法时响应检索转码进度的请求。但是因为我在VideoController 中使用Session 来存储一些变量以供跨多个请求使用,所以这种方式不适合我的问题。有没有更好的办法解决?
【问题讨论】:
-
伊万,你应该接受@AlexArt。 `s answer,因为它解决了你的问题
-
@Menahem 当然我做到了。但我仍然需要为我的问题找到最佳解决方案。
标签: c# asp.net ajax asp.net-mvc asynchronous