我想知道是否有任何设计模式允许将服务器端事件传递到网站?
我能想到的最好的办法是在触发事件时更新服务器上的某些状态,然后可能每隔一段时间通过 ajax 回调服务器以检查状态,并返回我需要的内容。这合适吗?有没有更好的方法来做到这一点?
我的应用程序是用 ASP.NET MVC4 编写的。
我想知道是否有任何设计模式允许将服务器端事件传递到网站?
我能想到的最好的办法是在触发事件时更新服务器上的某些状态,然后可能每隔一段时间通过 ajax 回调服务器以检查状态,并返回我需要的内容。这合适吗?有没有更好的方法来做到这一点?
我的应用程序是用 ASP.NET MVC4 编写的。
有几种方法可以处理这个问题,具体取决于您希望如何处理它以及您希望将哪些技术引入您的堆栈。
首先,定期对服务器上的控制器方法进行 ajax 调用以报告服务器的当前状态是非常好的,例如:如果在您的服务器上启动了一个长时间运行的任务,则通过控制器方法并定期轮询该方法是完全合理的。
另一种方法是使用一种称为 SignalR 的技术,它本质上允许您的服务器在您的客户端上调用 javascript 函数,我当然建议您研究一下。
小例子:
服务器:
public class Chat : Hub
{
public void Send(string message)
{
// Call the addMessage method on all clients
Clients.All.addMessage(message);
}
}
客户:
<script src="http://code.jquery.com/jquery-1.8.2.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-1.0.0-alpha2.min.js" type="text/javascript"></script>
<!-- If this is an MVC project then use the following -->
<!-- <script src="~/signalr/hubs" type="text/javascript"></script> -->
<script src="/signalr/hubs" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
// Proxy created on the fly
var chat = $.connection.chat;
// Declare a function on the chat hub so the server can invoke it
chat.client.addMessage = function (message) {
$('#messages').append('<li>' + message + '</li>');
};
$("#broadcast").click(function () {
// Call the chat method on the server
chat.server.send($('#msg').val());
});
// Start the connection
$.connection.hub.start();
});
</script>
<div>
<input type="text" id="msg" />
<input type="button" id="broadcast" value="broadcast" />
<ul id="messages">
</ul>
</div>
上面的例子取自这里: https ://github.com/SignalR/SignalR/wiki/QuickStart-Hubs
SignalR 网站可以在这里找到: http ://signalr.net/
我真的很喜欢 SignalR……它可能也会为你的程序员和用户提供最好的体验。
希望这可以帮助。
听起来你应该看看SignalR Project。这允许双向服务器通信。
您可以使用长轮询/彗星等待服务器事件,这意味着您应该向服务器发送 ajax 请求并且 ajax 请求不立即执行,请求将等待服务器事件,直到超时到期。
或者,您可以使用这样的 ajax 调用服务器事件来侦听服务器的事件,而无需 signalR 框架,例如:
[SessionState(SessionStateBehavior.ReadOnly)]
public class HomeController : Controller
{
static readonly ManualResetEvent Starter = new ManualResetEvent(false);
public ActionResult Index()
{
return View();
}
public String RiseServerEvent()
{
Starter.Set();
return "";
}
public async Task<String> WaitForServerEvent()
{
string contents = null;
var result = Task.Factory.StartNew(() =>
{
var reg = ThreadPool.RegisterWaitForSingleObject
(Starter, (state, @out) =>
{
contents = DateTime.Now.TimeOfDay.ToString();
}, "Some Data", -1, true);
Starter.WaitOne(10000);
contents = DateTime.Now.TimeOfDay.ToString();
});
await result;
return contents;
}
}