代码之家  ›  专栏  ›  技术社区  ›  Felipe Lima

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

  •  3
  • Felipe Lima  · 技术社区  · 15 年前

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

    理想情况下,我需要能够在服务器中得到一个javascript函数回调,以便能够在数据库中有任何新数据可用时调用javascript函数,而不必每隔5秒对服务器进行轮询。

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

    有没有任何方法可以用ASP.NET和Ajax来实现?

    3 回复  |  直到 15 年前
        1
  •  5
  •   JustLoren    15 年前

    您所说的另一种选择是某种形式的Comet风格的接口,在这种接口中,客户机发出一个请求,而服务器则一直保持该请求,直到有响应为止。wcf有pollingduplex绑定类型,但我不太确定如何在javascript中实现它。

    嗯,这似乎是一个非常相关的链接。上面写着Silverlight,但它是一个专门针对Ajax浏览器应用程序的应用程序: http://www.silverlightshow.net/news/AJAX-Client-for-HTTP-Polling-Duplex-WCF-Channel-in-Microsoft-Silverlight-3-.aspx

    更新: 我不明白为什么所有的备选答案都是“OMG自己做投票!”我们有专门的现代框架和协议来减少我们编写的手工代码的数量。wcf提供的pollingDuplex功能 确切地 您想要的,以及我提供的链接用纯JavaScript实现了该系统的客户端。

    不知道你还想要什么。

    更新2:

    对不起的, original article link .我们都认识到投票是 唯一解决方案 对于HTTP人员。作者正在寻找的主要区别是模拟推送与持续轮询。您可以通过向服务器放置一个长时间运行的轮询请求来实现模拟推送。有了正确的服务器体系结构,它将保持这个请求,直到它有数据为止。然后它会响应。此时,客户机立即重新请求。通过这种方式,您可以利用现有的HTTP请求响应循环来模拟对客户机的“推送”。

    这主要是通过 适当的服务器体系结构 就位。这样,你的请求就会进入睡眠状态,并以适当的方式被唤醒。这是一个比手动轮询答案好得多的范例,在这里您每5秒钟向服务器请求一次更新。需要响应的聊天应用程序 现在 从现在开始不是4.8秒 我在说。手动轮询(每隔5秒请求一次新数据)会出现滞后现象,在没有更新数据的期间,会导致不必要的请求/响应周期。

    从文章中:

    sl3duplex.js是一个 可重复使用的, 独立的javascript库 那个 实现HTTP的客户端 轮询双工 协议 兼容的 和PollingDuplexhtpbinding一起 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。

        2
  •  3
  •   roundcrisis    15 年前

    也许我遗漏了一些明显的东西,但是为什么不简单地从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请求。

    希望它有帮助

        3
  •  0
  •   Vitaliy Liptchinsky    15 年前

    由于防火墙等原因,在分布式环境中实现发布订阅模式非常困难。

    Afaik Microsoft正在使用智能池实现新的WCF绑定,以便在Silverlight和JavaScript中使用。但是,又是这样 轮询 .

    目前唯一的方法就是投票。