我想知道是否有任何设计模式允许将服务器端事件传递到网站?
我能想到的最好的办法是在服务器上设置一些状态,当事件被触发时,这些状态会被更新,然后可能会每隔一段时间通过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项目。这允许双向服务器通信。
您可以使用长轮询/彗星等待服务器事件。这意味着您应该向服务器发送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;
}
}