【发布时间】:2014-08-13 17:58:05
【问题描述】:
我有一个提供实时监控的网页。 基本上,页面每秒都会通过调用一个实际返回包含更新数据的 xml 的 web 表单来刷新其部分内容。这种方式很简单,但对我来说确实不太好。
它的js代码:
setInterval(function () {
GetAgents(responseId);
}, 1000);
//get Agents from b64 encoded xml
function AgentsHtml(b64) {
var html = "<div style=\"float: left; width: 45%; margin: 5px; padding: 5px; background: rgb(255, 255, 255); border-radius: 1px; box-shadow: " +
"4px 4px 6px rgba(0, 0, 0, 0.07); border-color: rgb(186,186,186); border-width: 1px; border-style: solid;\">\r\n@@agentdata@@\r\n</div>\r\n";
var xml = "";
var retVal = "";
try {
xml = decode64(b64);
if (xml != " ") {
var xmlDoc = $($.parseXML(xml));
var Agents = xmlDoc.find("WcfAgent");
Agents.each(function () {
var ActiveState = $(this).find('ActiveState').text();
var ActivityToken = "" + $(this).find('ActivityToken').text();
var Avalabilty = $(this).find('Avalabilty').text();
var Name = $(this).find('Name').text();
var SipUri = $(this).find('SipUri').text();
var StateColor = $(this).find('StateColor').text();
var pic = "/extensions/utsi001/images/dispo55x55.jpg";
if (ActivityToken != "" && ActivityToken != "off-work") {
pic = "/extensions/utsi001/images/conv55x55.jpg";
}
if (ActivityToken == "" && ActiveState == "UnavailableForIncomingCall" &&
(Avalabilty == "DoNotDisturb" ||
Avalabilty == "Busy")) {
pic = "/extensions/utsi001/images/pausa55x55.jpg";
}
if (ActivityToken == "" && Avalabilty == "Offline") {
pic = "/extensions/utsi001/images/off55x55.png";
}
var agent =
" <div style=\"float: left; width: 79%\">\r\n" +
" <p>" + Name + "</p>\r\n" +
" <p style=\"font-size: 12px; padding-left: 3px; margin-bottom: 3px; color: rgb(160,160,160);\">" + SipUri + "</p>\r\n" +
" <div style=\"height: 12px; background-color:" + StateColor + "; border:solid 1px rgb(186,186,186)\"></div>\r\n" +
" </div>\r\n" +
" <div style=\"float: right; width: 20%; margin-top: 5px\">\r\n" +
" <img alt=\"\" src=\"" + pic + "\" />\r\n" +
" </div>"
agent = html.replace("@@agentdata@@", agent);
retVal += agent;
});
}
else {
retVal = "";
}
}
catch (err) {
retVal = b64 + "<br />" + err;
}
return retVal;
}
//return agents ajax call
function GetAgents(responseId) {
link = "/somewhere/agents.aspx";
$.ajax({
type: "POST",
url: link,
data: "",
dataType: "text",
cache: false,
success: function (b64) {
var res = document.getElementById(responseId);
if (res != null && res != undefined) {
res.innerHTML = AgentsHtml(b64);
}
},
error: function (e) {
var res = document.getElementById(responseId);
if (res != null && res != undefined) {
res.innerHTML = e.responseText;
}
}
});
}
我对 Web 表单进行 ajax 调用的原因是因为我从自托管的 wcf 服务获取数据,该服务无法使用 javascript 跨域直接调用。
请。以上面的代码为例。在我的页面中,我不需要只更新一个数据.. 有几个.. 代理(上图)、来电、呼叫队列状态等。
从现在开始,这是一个新的编辑
感谢 Avner 的评论,我用 SignalR 做了一些测试,几乎解决了我的问题。 要明确问题是:“找到一种方法来避免使用 setInterval 触发任何给定的 ajax 调用”
在提到 WCF 服务的 Windows 服务中,我还添加了一个 SignalR webapp(集线器),似乎工作正常。
这是集线器类代码,因为我的实际需要是在我的服务器服务中发生一些事件后将信息推送到连接的 Web 客户端:
public class MyHub : Hub
{
//content will be a base64String containing a xml sheet
public void CallRefreshAgents(String content)
{
Clients.All.refreshAgents(content);
}
//...
// others methods just like the above
private static IHubContext _context = null;
public static IHubContext HubContext
{
get
{
if (_context == null)
_context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
return _context;
}
}
}
所以只要处理代理存在的变化,我就可以通过一个简单的调用来推送信息:
//pushVal it's a base64String containing a xml sheet
MyHub.HubContext.Clients.All.refreshAgents(pushVal);
在我的 Asp.Net Web 应用程序中,我只添加了对 jquery.signalr.js 的引用,而在监控页面中,js 客户端非常简单:
<head>
<script .... Al references needed .... </script>
<!-- service auto published js code -->
<script src="http://mySignalSelfHostedEndPoint/signalr/hubs"></script>
</head>
<body>
<script type="text/javascript">
var hub = null;
$(function () {
$.connection.hub.url = "http://mySignalSelfHostedEndPoint/signalr";
hub = $.connection.myHub;
$.connection.hub.start().done();
});
</script>
....
<script type="text/javascript">
//for initialization only during load/reload of the page
$(document).ready(
GetAgents("<%=DivIds.sections%>"));
$(function () {
hub.client.refreshAgents = function (b64) {
document.getElementById("<%=DivIds.sections%>").innerHTML = AgentsHtml(b64);
};
});
</script>
MyHub 类实现得好吗? 我真的不需要可以调用“CallRefreshAgents”的客户端,毕竟我想禁止这种调用发生
【问题讨论】:
-
你看过signalr吗? github.com/SignalR/SignalR
-
@Avner signalr 非常好的建议。不幸的是我不能使用第三方库。但我认为我走在正确的道路上,这要归功于:“..您可能听说过 WebSockets,这是一种新的 HTML5 API,可实现浏览器和服务器之间的双向通信。”来自信号器网站
-
我没有注意到 signalr 来自 Microsft,所以它像 jQuery 一样符合我的公司政策 :-) 我会进入..
标签: jquery asp.net ajax signalr