web-dev-qa-db-ja.com

データベースイベントを「リッスン」し、リアルタイムでページを更新する方法はありますか?

データベース変更イベント時にリアルタイムで更新できる単純なHTMLテーブルを作成する方法を探しています。具体的には、新しいレコードが追加されました。

つまり、エグゼクティブダッシュボードのようなものだと考えてください。セールが行われ、新しい行がデータベース(私の場合はMySQL)に追加された場合、Webページは新しい行でテーブルを「更新」する必要があります。

私はEVENT GATEWAYを使用して新しい情報をいくつか見ましたが、すべての例でColdfusionを「消費者」ではなく「プッシャー」として使用しています。 Coldfusionでイベントをゲートウェイに更新/プッシュし、応答も消費するようにします。

AJAXとCFの組み合わせを使用してこれを実行できる場合、お知らせください!

リアルタイムの更新を開始する場所を理解したいだけです。

前もって感謝します!!

編集/選択した回答の説明:

現時点では小規模に実装するのが最も簡単だったので、@ bpeterson76の答えに行き着きました。私は彼のDatatablesの提案が本当に好きで、それをリアルタイムに近い更新に使用しています。

私のサイトが(願わくば)大きくなるにつれて、すべてのユーザーが「リスナー」ページにアクセスし、その後データベースを照会するため、これがスケーラブルなソリューションになるかどうかはわかりません。クエリは比較的単純ですが、将来のパフォーマンスについてはまだ心配です。

しかし、私の意見では、HTML5がWeb標準になり始めているため、@ iKnowKungFooによって提案されたWeb Socketsメソッドが最善のアプローチである可能性が最も高いと言えます。長いポーリングを伴う彗星も素晴らしいアイデアですが、実装するのは少し面倒です/また、スケーリングの問題があるようです。

Web Socketsはリアルタイムに近づくための比較的簡単でスケーラブルな方法であるため、WebユーザーがHTML5をサポートする最新のブラウザーを採用し始めることを期待しましょう。

もし私が間違った決定をしたと感じたら、コメントを残してください。

最後に、すべてのソースコードを示します。

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>

コールドフュージョン:

<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>
33
AngeloS

これはそれほど難しくありません。簡単な方法は、.appendを介して追加することです。

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

要素をリアルタイムで追加することは完全に不可能です。ループ内で更新するAjaxクエリを実行して、変更を「キャッチ」する必要があります。したがって、完全にリアルタイムではなく、非常に、非常に近いものです。サーバーの負荷は異なるかもしれませんが、ユーザーは実際には違いに気付きません。

しかし、もっと複雑になる場合は、 DataTables を参照することをお勧めします。並べ替え、ページング、フィルタリング、制限、検索、ajaxロードなど、多くの新機能を提供します。そこから、ajaxを介して要素を追加してテーブルビューを更新するか、単にそのAPIを介して追加することができます。私はしばらくの間、アプリでDataTablesを使用しており、膨大な量のデータを使用可能にするナンバー1の機能として一貫して引用されてきました。

-編集-

明らかではないため、DataTableを更新するには、Datatables呼び出しを変数に設定します。

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

次に、これを実行して更新を行います。

  oTable.fnDraw(false);

更新-5年後の2016年2月:これは2011年よりも今日可能です。Backbone.jsなどの新しいJavascriptフレームワークは、データベースに直接接続し、変更、更新、またはデータの削除....これらのフレームワークの主な利点の1つです。さらに、Webサービスへのソケット接続を介して、UIにリアルタイムの更新を供給することができます。これにより、Webサービスをキャッチして処理することもできます。ここで説明した手法はまだ機能しますが、今日の物事を行う「ライブ」方法ははるかに多くあります。

7
bpeterson76

SSE(サーバー送信イベント)HTML5の機能を使用できます。

サーバー送信イベント(SSE)は、最初のクライアント接続が確立された後、サーバーがクライアントへのデータ送信を開始する方法を説明する標準です。これらは一般に、メッセージ更新または連続データストリームをブラウザクライアントに送信するために使用され、EventSourceと呼ばれるJavaScript APIを介したネイティブのクロスブラウザストリーミングを強化するように設計されています。クライアントはイベントソースを受信するために特定のURLを要求します。

簡単な例を示します

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

7
Jude Calimbas

MS SQLでは、Webサービスを呼び出すためにストアドプロシージャを起動できるテーブル挿入/削除/更新イベントにトリガーをアタッチできます。 WebサービスがCFベースの場合、イベントゲートウェイを使用してメッセージングサービスを呼び出すことができます。ゲートウェイをリッスンしているものはすべて、そのコンテンツを更新するように通知できます。つまり、MySQLがトリガーをサポートし、ストアドプロシージャを介してWebサービスにアクセスするかどうかを確認する必要があります。また、メッセージングゲートウェイをリッスンしているWebアプリケーションに何らかのコンポーネントが必要です。 Adobe Flexアプリケーションでは簡単に実行できますが、JavaScriptでアクセスできる同等のコンポーネントがあるかどうかはわかりません。

この答えはあなたの質問に直接対処することに近いものではありませんが、おそらくdbトリガーとCFメッセージングゲートウェイを使用して問題を解決する方法についていくつかのアイデアを与えるでしょう。

M.マッコネル

4

AJAX long polling。Place to start Comet

3

「現在の」技術では、Ajaxでの長いポーリングが唯一の選択肢だと思います。ただし、HTML5を使用できる場合は、必要な機能を提供するWebSocketをご覧ください。

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

WebSocketは、プッシュテクノロジーの一種である1つの(TCP)ソケットを介した双方向通信のための手法です。現時点では、まだW3Cによって標準化されています。ただし、ChromeおよびSafariの最新バージョンはWebSocketをサポートしています。

http://html5demos.com/web-socket

3

いいえ、サーバー側のコードを実行するdbコードはありません。ただし、新しいレコードが追加されたかどうかを確認するためにdbを定期的にポーリングするサービスを記述し、擬似リアルタイム更新が必要なコードを通知できます。

1
Feisty Mango

ブラウザは、Jabber/XMPPサーバーへのBOSH接続を介してリアルタイムの更新を受信できます。すべての断片はこの本で見つけることができます http://professionalxmpp.com/ これを強くお勧めします。 DBにレコードを追加するときにXMPPメッセージを送信できる場合は、必要なダッシュボードを比較的簡単に作成できます。 strophe.js、Jabber/XMPPサーバー(ejabberdなど)、httpバインド要求をプロキシするためのhttpサーバーが必要です。詳細はすべて本に記載されています。あなたの問題を解決するだろうと強く信じる必読書。

0

通知を達成する方法は、データベースの更新が正常にコミットされた後、リスニングシステムまたはWebページに変更が発生したことを通知するイベントを発行することです。 最近のブログ投稿 で電子商取引ソリューションを使用してこれを行う1つの方法を詳しく説明しました。ブログの投稿では、ASP.NETでイベントをトリガーする方法を示していますが、最終的にトリガーはREST= API呼び出しによって実行されるため、他の言語でも同じことが簡単に行えます。

このブログ投稿のソリューションでは Pusher を使用していますが、独自のリアルタイムサーバーをインストールできない、またはアプリとリアルタイムサーバー間の通信にメッセージキューを使用できなかった理由はありません。 Webページまたはクライアントアプリケーションへの通知。

0
leggetter