我正在開發一個使用ASP.NET MVC的視頻網站。對Action方法的兩個並行ajax請求排隊,爲什麼?
我想在我的應用程序中使用的一項功能是轉換視頻。但是,由於轉碼過程可能非常耗時,我想向客戶端用戶展示該過程的進度。
因此,我的模式是使用一個控制器動作來處理整個轉碼過程並將其進度寫入存儲在服務器上的文件中。同時我使用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 retireving 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
行動方法一切正常。問題是,GetProgress
方法將永遠不會被調用,直到Transcode
操作完成其整個過程。那麼我的代碼有什麼問題?我如何修改它以使這兩個動作自發地工作以實現我的目標?
更新:
根據Alex的答案,我發現我的問題是由Asp.Net框架的會話鎖定機制造成的。因此,禁用VideoController
的SessionState
或將其設置爲只讀會使控制器響應轉碼視頻操作方法執行時檢索轉碼進度的請求。但是因爲我在我的VideoController
中使用Session
來存儲一些變量以供跨多個請求使用,所以這種方式不適合我的問題。有沒有更好的方法來解決它?
伊萬,你應該接受@AlexArt。的答案,因爲它解決了你的問題 – Menahem
@Menahem當然,我做到了。但我仍然需要爲我的問題找到最佳解決方案。 – Ivan