是否可以使用JavaScript订阅c#事件?

时间:2009-10-14 14:10:52

标签: c# asp.net javascript

我正在开发一个Web应用程序,需要经常轮询服务器数据库并检查客户端的任何可用数据。

理想情况下,我需要能够在服务器中获取javascript函数回调,以便能够在数据库上有任何新数据时调用javascript函数,而不必每5次轮询服务器秒。

简化,我需要能够在服务器中调用一个方法并传递一个js函数作为回调参数。我想避免重复轮询服务器的开销。

有没有办法可以用asp.net和ajax做到这一点?

3 个答案:

答案 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">
                &nbsp;
            </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">
                &nbsp;
            </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中使用。但是,再一次,它是民意调查

现在唯一的出路就是投票。