web-dev-qa-db-fra.com

Est-il possible d'écouter un événement de base de données et de mettre à jour une page en temps réel?

Je cherche un moyen de créer un tableau HTML simple pouvant être mis à jour en temps réel à la suite d'un événement de changement de base de données; spécifiquement un nouvel enregistrement ajouté.

En d'autres termes, pensez-y comme à un tableau de bord exécutif. Si une vente est faite et qu'une nouvelle ligne est ajoutée dans une base de données (MySQL dans mon cas), la page Web doit alors "actualiser" le tableau avec la nouvelle ligne.

J'ai vu des informations sur le nouveau en utilisant EVENT GATEWAY mais tous les exemples utilisent Coldfusion comme "pousseur" et non comme "consommateur". J'aimerais que Coldfusion mette à jour/envoie un événement à la passerelle et consomme la réponse.

Si cela peut être fait en utilisant une combinaison de AJAX et de CF, faites-le moi savoir! 

Je cherche vraiment à comprendre où commencer avec la mise à jour en temps réel.

Merci d'avance!!

EDIT/Explication de la réponse sélectionnée:

Je me suis retrouvé avec la réponse de @ bpeterson76 car pour le moment, il était plus facile de la mettre en œuvre à petite échelle. J'aime beaucoup sa suggestion concernant Datatables, et c’est ce que j’utilise pour mettre à jour en temps quasi réel.

Comme mon site s'agrandit (j'espère), je ne sais pas si ce sera une solution évolutive, car chaque utilisateur s'affichera sur une page "écouteur", puis interrogera ensuite ma base de données. Ma requête est relativement simple, mais je suis toujours préoccupé par les performances futures.

À mon avis cependant, alors que HTML5 commence à devenir le standard Web, la méthode Web Sockets proposée par @iKnowKungFoo est probablement la meilleure approche. Comet avec de longues interrogations est également une excellente idée, mais il est un peu fastidieux à mettre en œuvre/semble également présenter des problèmes d’agrandissement.

Espérons donc que les utilisateurs Web commencent à adopter des navigateurs plus modernes prenant en charge HTML5, car Web Sockets est un moyen relativement facile et évolutif de se rapprocher du temps réel.

Si vous pensez que j'ai pris la mauvaise décision, veuillez laisser un commentaire.

Enfin, voici un code source pour tout cela:

Javascript:

Notez que ceci est une implémentation très simple. Il cherche seulement à voir si le nombre d'enregistrements dans le datatable actuel a changé et si ainsi mettre à jour la table et lancer une alerte. Le code de production est beaucoup plus long et plus complexe. Ceci montre simplement un moyen simple d'obtenir une mise à jour proche de celle en temps réel.

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

Fusion froide:

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

Ce n'est pas trop difficile. Le moyen le plus simple serait d’ajouter via .append:

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

L'ajout d'éléments en temps réel n'est pas tout à fait possible. Vous devez exécuter une requête Ajax qui se met à jour en boucle pour "attraper" le changement. Donc, pas tout à fait en temps réel, mais très, très proche de cela. Votre utilisateur ne verrait vraiment pas la différence, bien que la charge de votre serveur puisse l'être.

Mais si vous voulez vous impliquer davantage, je vous conseillerais de regarder DataTables . Il vous offre un certain nombre de nouvelles fonctionnalités, notamment le tri, la pagination, le filtrage, la limitation, la recherche et le chargement ajax. À partir de là, vous pouvez soit ajouter un élément via ajax et actualiser la vue table, soit simplement ajouter dessus via son API. J'utilise DataTables dans mon application depuis un certain temps déjà et ils ont été constamment cités comme étant la fonctionnalité numéro 1 qui rend l'immense quantité de données utilisable.

--Modifier --

Parce que ce n'est pas évident, pour mettre à jour le DataTable que vous appelez, définissez votre appel Datatables sur une variable:

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

Puis lancez ceci pour faire la mise à jour: 

  oTable.fnDraw(false);

MISE À JOUR - 5 ans plus tard, février 2016: C’est beaucoup plus possible aujourd’hui qu’en 2011. Les nouveaux frameworks Javascript tels que Backbone.js peuvent se connecter directement à la base de données et déclencher des modifications sur les éléments de l’UI, y compris des tables mettre à jour ou supprimer des données ... c'est l'un des principaux avantages de ce cadre. De plus, les interfaces utilisateur peuvent recevoir des mises à jour en temps réel via des connexions de socket vers un service Web, qui peut également être intercepté et traité. Bien que la technique décrite ici fonctionne toujours, il existe beaucoup plus de façons de faire en direct.

7
bpeterson76

Vous pouvez utiliser SSE (événements envoyés par le serveur), une fonctionnalité de HTML5.

SSE (Server-Sent Events) est une norme décrivant comment les serveurs peuvent initier la transmission de données vers les clients une fois la connexion client établie. Ils sont couramment utilisés pour envoyer des mises à jour de messages ou des flux de données continus à un client de navigateur et sont conçus pour améliorer la diffusion en continu sur plusieurs navigateurs via une API JavaScript appelée EventSource, via laquelle un client demande une URL particulière pour recevoir un flux d'événements.

heres un exemple simple

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

7
Jude Calimbas

Dans MS SQL , vous pouvez associer un déclencheur à un événement table insert/delete/update pouvant déclencher un processus stocké pour appeler un service Web. Si le service Web est basé sur CF, vous pouvez, à son tour, appeler un service de messagerie à l'aide de passerelles d'événement. Tout ce qui écoute la passerelle peut être notifié pour actualiser son contenu. Cela dit, vous devez voir si MySQL prend en charge les déclencheurs et l’accès aux services Web via des procédures stockées. Dans votre application Web, vous devez également disposer d'une sorte de composant écoutant la passerelle de messagerie. C'est facile à faire dans les applications Adobe Flex, mais je ne sais pas s'il existe des composants comparables accessibles en JavaScript. 

Même si cette réponse ne répond pas directement à votre question, elle vous donnera peut-être quelques idées sur la façon de résoudre le problème en utilisant des déclencheurs de base de données et des passerelles de messagerie CF.

M. McConnell

4
Michael McConnell

Découvrez AJAX longue interrogation. Lieu de départ Comet

3
Marko Jovanović

Avec les technologies "actuelles", je pense que les longues interrogations avec Ajax sont votre seul choix. Cependant, si vous pouvez utiliser HTML5, vous devriez jeter un coup d'œil à WebSockets qui vous offre les fonctionnalités souhaitées.

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

WebSockets est une technique de communication bidirectionnelle sur un socket (TCP), un type de technologie Push. Pour le moment, il est toujours en cours de standardisation par le W3C; Cependant, les dernières versions de Chrome et Safari prennent en charge WebSockets.

http://html5demos.com/web-socket

3
Adrian J. Moreno

Non, vous ne pouvez avoir aucun code de base de données exécutant le code côté serveur. Mais vous pouvez écrire un service pour interroger régulièrement la base de données pour voir si un nouvel enregistrement a été ajouté, puis notifier le code que vous avez et qui nécessite des mises à jour pseudo-temps réel.

1
Feisty Mango

Le navigateur peut recevoir des mises à jour en temps réel via une connexion BOSH au serveur Jabber/XMPP. Tous les morceaux peuvent être trouvés dans ce livre http://professionalxmpp.com/ que je recommande vivement. Si vous pouvez de toute façon envoyer un message XMPP lors de l'ajout d'un enregistrement dans votre base de données, il est relativement facile de créer le tableau de bord souhaité. Vous avez besoin de strophe.js, du serveur Jabber/XMPP (par exemple, ejabberd), du serveur http pour le proxy des demandes de liaison http. Tous les détails peuvent être trouvés dans le livre. Une lecture incontournable qui, je crois fermement, résoudra votre problème.

0
Gjorgji Tashkovski

J'obtiendrais cette notification une fois que la mise à jour de la base de données a été validée avec succès. Je publierais un événement qui indiquerait à tout système d'écoute ou même à toute page Web que le changement a eu lieu. J'ai détaillé une façon de le faire en utilisant une solution de commerce électronique dans un récent article de blog . La publication de blog montre comment déclencher l'événement dans ASP.NET, mais la même chose peut être facilement réalisée dans n'importe quel autre langage puisqu'un déclencheur est finalement exécuté via un appel d'API REST.

La solution de ce billet de blog utilise Pusher mais il n’ya aucune raison pour que vous ne puissiez pas installer votre propre serveur temps réel ou utiliser un Message Queue pour la communication entre votre application et le serveur temps réel, qui transmettrait alors la notification à la page Web ou l'application client.

0
leggetter