我的服务器计算机上存在一个文本文件,该文件不断更新(大约一次约5秒)。在我的网页上,我想要一个div来在MVC中使用jQuery实时显示这个文件。
我已经jQuery timer正在运行,但文件未显示。我的计划是让jQuery每5秒加载一次Controller Action并让这个动作返回一个FilePathResult。
剧本:
$(function () {
var streamer = $("div.wrapper div.streamer");
//===
var active = false;
$(document).ready(function () {
$(".uncontrolled-interval p", streamer).everyTime(1000, function () {
$(this).load("/Home/Stream");
});
});
});
观点:
<div class="wrapper">
<div class="streamer">
<div id="uncontrolled-interval" style=" height:420px; width:1200px; background-color:Black; color:White; overflow: auto; " ></div>
</div>
</div>
控制器:
Public Function Stream() As ActionResult
Return File(ConfigurationManager.AppSettings.Item("LiveStreamPath"), "text/plain")
End Function
LiveStreamPath
包含文本文件的路径。我正在考虑在Action中创建一个StreamReader。我可以使用哪种实现来传输此文件?
答案 0 :(得分:0)
有两种方法:POLL和PUSH。
您采用的方法是让客户端定期轮询服务器,方法是发送AJAX请求并显示结果,即使内容未更改。在这种情况下,您有一个共享资源。此共享资源是文件。该资源可以由不同的线程/进程同时访问。文件的问题是,当一个线程正在写入文件时(您说文件每5秒更新一次),如果另一个线程尝试从中读取,则很可能会失败或从文件中获取不一致的数据。因此,如果您决定采用轮询方法,则必须确保正确同步对此文件的访问。根据它是写入文件的另一个线程还是另一个进程,可能有不同的技术来实现这一点。例如,如果它是另一个线程,您可以使用Monitor.Enter(相当于C#lock
)。对于共享资源的跨进程同步,您可以使用Mutex。
第二种方法是PUSH方法。在此模型中,服务器在文件更新时向客户端发送通知。它是一个更加优化,因为客户端不会因为大量的AJAX请求而淹没服务器。有不同的技术来实现这一点。例如,在HTML5中,您可以使用WebSockets。微软正在开发一个名为Signalr的优秀平台,它可以非常简单地实现这一场景。
答案 1 :(得分:0)
我刚刚为jquery做了一个小测试应用程序(测试背景,没有让前景工作得很漂亮。通过点击链接来调用它,它发送1个请求来启动进程并触发监视器。< / p>
function startJob() {
$.get('<%=ResolveUrl("~/Background/StartJob.ashx") %>');
setTimeout('updateStatus()', 500);
}
function updateStatus() {
$("#results").load('<%=ResolveUrl("~/Background/ReadStatus.ashx") %>');
setTimeout('updateStatus()', 500);
}
在后台,您可以使用File.ReadAllText()执行此操作,而不会打开任何锁定。
对于写作,您可以使用File.AppendText() / AppendBytes()
等,它将附加到文件而不会对其进行读锁定。我很少使用streamwriter和所有FileShare参数,这通常足以用于Web应用程序。
是的,如果您经常更新,并且有大量数据,您可能会得到不一致的读取。如果这不是问题(例如,没有繁重的处理,ui并不在意),那么保持原样。如果用户界面确实关心,请使用ReaderWriterLockSlim。
表示一个锁,用于管理对资源的访问,允许多个线程进行读取或独占访问以进行写入。