我正在开发一个Web应用程序,需要经常轮询服务器数据库并检查客户端的任何可用数据。
理想情况下,我需要能够在服务器中获取javascript函数回调,以便能够在数据库上有任何新数据时调用javascript函数,而不必每5次轮询服务器秒。
简化,我需要能够在服务器中调用一个方法并传递一个js函数作为回调参数。我想避免重复轮询服务器的开销。
有没有办法可以用asp.net和ajax做到这一点?
答案 0 :(得分:5)
您正在谈论的替代方案是某种形式的COMET样式接口,其中客户端发出请求并且服务器保留它直到它有响应。 WCF具有PollingDuplex绑定类型,但我并不十分确定如何在javascript中实现它。
嗯,这似乎是一个非常相关的链接。它说Silverlight到处都是,但它专门用于AJAX浏览器应用程序: http://www.silverlightshow.net/news/AJAX-Client-for-HTTP-Polling-Duplex-WCF-Channel-in-Microsoft-Silverlight-3-.aspx
更新: 我不明白为什么所有的替代答案相当于“你自己做轮询!”我们有专门的现代框架和协议来减少我们编写的手动代码量。 WCF提供的PollingDuplex功能完全你想要的东西,我提供的链接用纯JavaScript实现该系统的客户端。
不确定你还想要什么。
更新2:
抱歉,original article link。我们都认识到,轮询是HTTP人员的唯一解决方案。作者寻找的主要区别是模拟推送与常量轮询。您可以通过将长时间运行的轮询请求发送到服务器来实现模拟推送。有了正确的服务器架构,它就会保留该请求,直到它有数据为止。然后它会回应。此时,客户端立即重新请求。通过这种方式,您可以利用现有的HTTP请求 - 响应周期来模拟“推送”到客户端。
这主要是通过适当的适当的服务器架构来实现的。这样你的请求就会以适当的方式进入睡眠状态并被唤醒。这是一个比手动轮询答案更好的范例,您每隔5秒就会要求服务器进行更新。现在需要响应 而不是4.8s的Chatty应用程序是什么 我在说。手动轮询(每5秒发出一次新数据请求)会出现滞后现象,在没有数据更新的期间,会导致不必要的请求/响应周期。
来自文章:
sl3duplex.js是可重用的, 独立的JavaScript库那个 实现HTTP的客户端 轮询双工 协议 兼容 使用PollingDuplexHttpBinding System.ServiceModel.PollingDuplex.dll
从下载中的.HTM文件:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>AJAX client for HTTP polling duplex WCF channel in Microsoft Silverlight 3</title>
<script src="sl3duplex.js"></script>
<script src="pubsub.js"></script>
<script language="javascript">
var sl3duplex = org.janczuk.sl3duplex;
var proxy = null;
function addNotification(text) {
var notifications = document.getElementById("notifications");
notifications.value += text + "\n";
notifications.scrollTop = notifications.scrollHeight;
}
function alignUIWithConnectionState(connected) {
document.getElementById("topicName").disabled =
document.getElementById("subscribeButton").disabled = connected ? "disabled" : null;
document.getElementById("publishText").disabled = connected ? null : "disabled"
}
function onSubscribe() {
proxy = new sl3duplex.Sl3DuplexProxy({
url: window.location.href.substring(0, window.location.href.lastIndexOf("/")) + "/PubSubService.svc",
onMessageReceived: function(body) {
addNotification("SERVER NOTIFICATION: " + (new sl3duplex.NotificationMessage(body)).text);
},
onError: function(args) {
addNotification("ERROR: " + args.error.message);
alignUIWithConnectionState(false);
}
});
alignUIWithConnectionState(true);
var topic = document.getElementById("topicName").value;
proxy.send({ message: new sl3duplex.SubscribeMessage(topic),
onSendSuccessful: function(args) {
addNotification("CLIENT ACTION: Subscribed to topic " + topic);
}
});
}
function onPublish(event) {
if (event.keyCode == 13) {
var publishText = document.getElementById("publishText");
var content = publishText.value;
publishText.value = "";
var topic = document.getElementById("topicName").value;
proxy.send({ message: new sl3duplex.PublishMessage(topic, content),
onSendSuccessful: function(args) {
addNotification("CLIENT ACTION: Published to topic " + topic + ": " + content);
}
});
}
}
</script>
</head>
<body bgcolor="Tomato">
<table style="width: 640px; font-family: Arial, Helvetica, sans-serif; font-size: 11px;"
cellspacing="2" align="center">
<tr>
<td colspan="2">
Topic to subscribe and publish to:
</td>
</tr>
<tr>
<td style="width: 448px">
<input id="topicName" type="text" value="Dante" style="width: 100%" />
</td>
<td style="width: 192px">
<input id="subscribeButton" type="button" value="Subscribe" style="width: 100%" onclick="onSubscribe();" />
</td>
</tr>
<tr>
<td colspan="2">
</td>
</tr>
<tr>
<td colspan=2>
Notifications:
</td>
</tr>
<tr>
<td colspan="2">
<textarea id="notifications" name="S1" rows="18" readonly="readonly" style="width: 100%;
background-color: ButtonFace"></textarea>
</td>
</tr>
<tr>
<td colspan="2">
</td>
</tr>
<tr>
<td colspan="2">
Enter text to publish and press Enter:
</td>
</tr>
<tr>
<td colspan="2">
<input id="publishText" type="text" style="width: 100%" disabled="disabled" onkeypress="onPublish(event);" />
</td>
</tr>
</table>
</body>
</html>
没有创建silverlight对象或引用库。我也可以将.JS文件转储到这里,以表明它只是一个“可重用,独立的JavaScript库,它实现了HTTP轮询双工协议的客户端”,并且不依赖于安装Silverlight。 / p>
答案 1 :(得分:3)
也许我错过了一些明显的东西,但为什么不只是简单地从ajax做一个GET请求(你可以轻松地使用jQuery或任何主要的javascript框架),然后在回复时你可以做任何你需要更新你的视图
这是here
的快速复制和粘贴模式Ext.Ajax.request({ url : 'http://yourdomain.com/controller/Action' , params : { action : 'getDate' }, method: 'GET', success: function ( result, request ) { Ext.MessageBox.alert('Success', 'Data return from the server: '+ result.responseText); //.. do more view related stuff here , if this was a grid your would probably reload the store }, failure: function ( result, request) { Ext.MessageBox.alert('Failed', result.responseText); } });
当然,您需要使用计时器以固定的时间间隔执行此ajax请求。
希望有所帮助
答案 2 :(得分:0)
由于防火墙等原因,在分布式环境中实现发布 - 订阅模式非常困难。
AFAIK Microsoft正在使用智能池实现新的WCF绑定,以便在SIlverlight和javascript中使用。但是,再一次,它是民意调查。
现在唯一的出路就是投票。