有没有办法'监听'数据库事件并实时更新页面?

时间:2011-06-24 17:59:30

标签: mysql ajax coldfusion real-time

我正在寻找一种方法来创建一个简单的HTML表格,可以在数据库更改事件时实时更新;特别是添加了新记录。

换句话说,将其视为执行仪表板。如果进行了销售并在数据库中添加了新行(在我的情况下是MySQL),那么网页应该用新行“刷新”表格。

我已经看到有关使用EVENT GATEWAY的新信息,但所有示例都使用Coldfusion作为“推动者”,而不是“消费者”。我想让Coldfusion将事件更新/推送到网关并消耗响应。

如果可以使用AJAX和CF的组合完成,请告诉我!

我真的只是想了解从何处开始实时更新。

提前谢谢!!

编辑/所选答案的说明:

我最终选择了@ bpeterson76的答案,因为目前这是最容易实现的。我真的很喜欢他的Datatables建议,这就是我用来近乎实时更新的内容。

随着我的网站越来越大(希望如此),我不确定这是否是一个可扩展的解决方案,因为每个用户都会点击“监听器”页面,然后再查询我的数据库。我的查询相对简单,但我仍然担心将来的表现。

在我看来,随着HTML5开始成为Web标准,@ iKnowKungFoo建议的Web套接字方法很可能是最好的方法。使用长轮询的Comet也是一个好主意,但它实现起来有点麻烦/似乎也有一些扩展问题。

所以,我们希望网络用户开始采用支持HTML5的更现代的浏览器,因为Web套接字是一种相对简单且可扩展的方式来接近实时。

如果您认为我做出了错误的决定,请发表评论。

最后,这里有一些源代码:

使用Javascript:

请注意,这是一个非常简单的实现。它只是想查看当前数据表中的记录数是否已更改,如果是,则更新表并发出警报。生产代码更长,更复杂。这只是展示了一种接近实时更新的简单方法。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js"></script>
<script type="text/javascript" charset="utf-8">

var originalNumberOfRecsInDatatable = 0;
var oTable;

var setChecker = setInterval(checkIfNewRecordHasBeenAdded,5000); //5 second intervals

function checkIfNewRecordHasBeenAdded() {

        //json object to post to CFM page
        var postData = {
        numberOfRecords:  originalNumberOfRecsInDatatable 
        };

        var ajaxResponse = $.ajax({
        type: "post",
        url: "./tabs/checkIfNewItemIsAvailable.cfm",
        contentType: "application/json",
        data: JSON.stringify( postData )
        })

        // When the response comes back, if update is available
        //then re-draw the datatable and throw an alert to the user
        ajaxResponse.then(
        function( apiResponse ){

         var obj = jQuery.parseJSON(apiResponse);

         if (obj.isUpdateAvail == "Yes")
         {              
            oTable = $('#MY_DATATABLE_ID').dataTable();
            oTable.fnDraw(false);

            originalNumberOfRecsInDatatable = obj.recordcount;

            alert('A new line has been added!');
         }

        }
        );

    }
</script>

ColdFusion的:

<cfset requestBody = toString( getHttpRequestData().content ) />

<!--- Double-check to make sure it's a JSON value. --->
<cfif isJSON( requestBody )>

<cfset deserializedResult = deserializeJSON( requestBody )>

<cfset numberOFRecords = #deserializedResult.originalNumberOfRecsInDatatable#>


<cfquery  name="qCount" datasource="#Application.DBdsn#" username="#Application.DBusername#" password="#Application.DBpw#">
    SELECT COUNT(ID) as total
    FROM myTable
</cfquery>

<cfif #qCount.total# neq #variables.originalNumberOfRecsInDatatable#>
    {"isUpdateAvail": "Yes", "recordcount": <cfoutput>#qCount.total#</cfoutput>}
<cfelse>
    {"isUpdateAvail": "No"}
</cfif>


</cfif>

8 个答案:

答案 0 :(得分:7)

这并不太难。简单的方法是添加via .append:

$( '#table > tbody:last').append('<tr id="id"><td>stuff</td></tr>');

实时添加元素并非完全可能。您必须运行一个Ajax查询,该查询在循环中更新以“捕获”更改。所以,不是完全实时,而是非常非常接近它。您的用户确实不会注意到差异,尽管您的服务器可能会加载。

但是如果你想要更多参与,我建议你看DataTables。它为您提供了许多新功能,包括排序,分页,过滤,限制,搜索和ajax加载。从那里,您可以通过ajax添加元素并刷新表视图,或者只是通过其API附加。我已经在我的应用程序中使用DataTables已有一段时间了,并且它们一直被认为是能够使用大量数据的第一功能。

- 编辑 -

因为不明显,要更新您调用的DataTable,请将Datatables调用设置为变量:

var oTable = $('#selector').dataTable();

然后运行它来进行更新:

  oTable.fnDraw(false);

更新 - 5年后,2016年2月: 今天比2011年更加可能。新的Javascript框架(如Backbone.js)可以直接连接到数据库并触发UI元素的更改,包括更改,更新或删除数据的表....这是其中之一这些框架的主要好处。此外,UI可以通过套接字连接提供给Web服务的实时更新,然后也可以捕获并执行操作。虽然这里描述的技术仍然有效,但今天有更多“实时”的做事方式。

答案 1 :(得分:7)

您可以在HTML5中使用SSE(服务器已发送事件)功能。

服务器发送事件(SSE)是描述服务器在建立初始客户端连接后如何向客户端发起数据传输的标准。它们通常用于向浏览器客户端发送消息更新或连续数据流,旨在通过名为EventSource的JavaScript API增强本机跨浏览器流,客户端通过该API请求特定URL以接收事件流。 / p>

这是一个简单的例子

http://www.w3schools.com/html/html5_serversentevents.asp

答案 2 :(得分:4)

MS SQL 中,您可以将触发器附加到表插入/删除/更新事件,该事件可以触发存储过程以调用Web服务。如果Web服务是基于CF的,则可以使用事件网关调用消息传递服务。可以通知任何收听网关的内容以刷新其内容。也就是说,你必须看看 MySQL 是否支持触发器并通过存储过程访问Web服务。您还必须在Web应用程序中使用某种正在侦听消息传递网关的组件。在Adobe Flex应用程序中很容易做到,但我不确定是否有类似的组件可以在JavaScript中访问。

虽然这个答案并没有直接解决你的问题,但它可能会给你一些关于如何使用db触发器和CF消息传递网关来解决问题的想法。

微米。麦康奈尔

答案 3 :(得分:3)

查看AJAX长轮询。 开始Comet

的地方

答案 4 :(得分:3)

使用“当前”技术,我认为使用Ajax进行长时间轮询是您唯一的选择。但是,如果你可以使用HTML5,你应该看看WebSockets,它为你提供了你想要的功能。

http://net.tutsplus.com/tutorials/javascript-ajax/start-using-html5-websockets-today/

  

WebSockets是一种通过一种(TCP)套接字进行双向通信的技术,这是一种PUSH技术。目前,它仍然由W3C标准化;但是,最新版本的Chrome和Safari都支持WebSockets。

http://html5demos.com/web-socket

答案 5 :(得分:1)

不,你不能有任何db代码执行服务器端代码。但您可以编写一个服务来定期轮询数据库以查看是否添加了新记录,然后通知您需要伪实时更新的代码。

答案 6 :(得分:0)

浏览器可以通过BOSH连接到Jabber / XMPP服务器接收实时更新。所有的点点都可以在本书http://professionalxmpp.com/中找到,我强烈推荐。如果您可以在数据库中添加记录时以任何方式发送XMPP消息,那么构建所需的仪表板相对容易。你需要strophe.js,Jabber / XMPP服务器(例如ejabberd),http服务器来代理http-bind请求。所有细节都可以在书中找到。必读,我坚信我会解决你的问题。

答案 7 :(得分:0)

我实现通知的方式是在成功提交数据库更新之后,我将发布一个事件,告诉任何侦听系统甚至网页发生了更改。我已经详细介绍了使用recent blog post中的电子商务解决方案实现此目的的一种方法。博客文章展示了如何在ASP.NET中触发事件,但同样的事情可以用任何其他语言轻松完成,因为最终触发器是通过REST API调用执行的。

此博客文章中的解决方案使用Pusher,但没有理由说您无法安装自己的实时服务器或使用Message Queue在您的应用和实时服务器之间进行通信,这会推送通知网页或客户端应用程序。