Есть ли способ «прослушать» событие базы данных и обновить страницу в режиме реального времени? - PullRequest
33 голосов
/ 24 июня 2011

Я ищу способ создать простую таблицу HTML, которая может обновляться в режиме реального времени при изменении базы данных;в частности, добавлена ​​новая запись.

Другими словами, думайте об этом как о приборной панели для руководителей.Если продажа сделана и новая строка добавлена ​​в базу данных (MySQL в моем случае), то веб-страница должна «обновить» таблицу новой строкой.

Я видел некоторую информацию о новом использованииEVENT GATEWAY но во всех примерах Coldfusion используется в качестве «толкача», а не «потребителя».Я бы хотел, чтобы Coldfusion обновлял / отправлял событие на шлюз, а также использовал ответ.

Если это можно сделать с использованием комбинации AJAX и CF, пожалуйста, дайте мне знать!

Я просто хочу понять, с чего начать обновление в реальном времени.

Заранее спасибо !!

РЕДАКТИРОВАТЬ / Объяснение выбранногоответ:

Я закончил с ответом @ bpeterson76, потому что на данный момент его было проще всего реализовать в небольшом масштабе.Мне очень нравится его предложение Datatables, и именно это я использую для обновления в режиме реального времени.

Поскольку мой сайт становится все больше (надеюсь), я не уверен, будет ли это масштабируемым решением, посколькукаждый пользователь будет заходить на страницу «слушателя», а затем запрашивать мою БД.Мой запрос относительно прост, но я все еще беспокоюсь о производительности в будущем.

По моему мнению, хотя HTML5 начинает становиться веб-стандартом, метод Web Sockets, предложенный @iKnowKungFoo, скорее всего,лучший подход.Комета с длительным опросом также является отличной идеей, но ее реализация немного трудоемка / также, похоже, имеет некоторые проблемы с масштабированием.

Итак, будем надеяться, что веб-пользователи начнут использовать более современные браузеры, поддерживающие 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 ]

7 голосов
/ 27 июля 2013

Вы можете использовать функцию SSE (Server Sent Events) в HTML5.

Server-Sent Events (SSE) - это стандарт, описывающий, как серверы могут инициировать передачу данных клиентам после установления первоначального клиентского соединения.,Они обычно используются для отправки обновлений сообщений или непрерывных потоков данных клиенту браузера и предназначены для расширения встроенной потоковой передачи через браузер через API-интерфейс JavaScript, называемый EventSource, через который клиент запрашивает определенный URL-адрес для получения потока событий.

вот простой пример

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

7 голосов
/ 24 июня 2011

Это не так уж сложно.Простой способ - добавить через .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);

UPDATE -- 5 лет спустя, февраль 2016 года. Сегодня это гораздо более возможно, чем в 2011 году. Новые платформы Javascript, такие как Backbone.js, могут напрямую подключаться к базе данных и инициировать изменения в элементах пользовательского интерфейса, включая таблицы при изменении, обновлении или удаленииданные .... это одно из основных преимуществ этих структур.Кроме того, пользовательские интерфейсы могут получать обновления в режиме реального времени через сокетные соединения с веб-службой, которые затем могут быть перехвачены и обработаны.Хотя описанная здесь техника все еще работает, сегодня существует гораздо больше «живых» способов ведения дел.

4 голосов
/ 24 июня 2011

В MS SQL вы можете прикрепить к событию вставки / удаления / обновления таблицы триггер, который может запустить хранимый процесс для вызова веб-службы.Если веб-служба основана на CF, вы можете, в свою очередь, вызвать службу обмена сообщениями, используя шлюзы событий.Все, что слушает шлюз, может быть уведомлено об обновлении его содержимого.Тем не менее, вы должны увидеть, если MySQL поддерживает триггеры и доступ к веб-сервисам через хранимые процедуры.Вы также должны иметь какой-то компонент в своем веб-приложении, который слушает шлюз обмена сообщениями.Это легко сделать в приложениях Adobe Flex, но я не уверен, есть ли сопоставимые компоненты, доступные в JavaScript.

Хотя этот ответ не приближается к непосредственному решению вашего вопроса, возможно, он даст вам некоторые идеи относительно того, как решить проблему с использованием триггеров db и шлюзов обмена сообщениями CF.

M.Макконнелл

3 голосов
/ 24 июня 2011

С «современными» технологиями я думаю, что длительный опрос с помощью 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

3 голосов
/ 24 июня 2011

Проверьте длинный опрос AJAX.Место для начала Комета

1 голос
/ 24 июня 2011

Нет, вы не можете иметь какой-либо код БД для выполнения кода на стороне сервера. Но вы могли бы написать сервис для периодического опроса базы данных, чтобы увидеть, была ли добавлена ​​новая запись, а затем уведомить ваш код, который требует псевдо-обновления в реальном времени.

0 голосов
/ 05 июля 2011

Когда я получу уведомление, то после успешного завершения обновления базы данных я опубликую событие, которое сообщит любым прослушивающим системам или даже веб-страницам о том, что произошло изменение.Я подробно описал один из способов сделать это с помощью решения для электронной коммерции в недавнем сообщении в блоге .В блоге показано, как вызвать событие в ASP.NET, но то же самое можно легко сделать на любом другом языке, поскольку в конечном итоге триггер выполняется с помощью вызова API REST.

Решение в этом блоге использует Pusher но нет причины, по которой вы не можете установить свой собственный сервер в реальном времени или использовать очередь сообщений для связи между вашим приложением и сервером в реальном времени, которая затем отправит уведомление на веб-страницу или клиентуприменение.

0 голосов
/ 28 июня 2011

Браузер может получать обновления в режиме реального времени через соединение BOSH с сервером Jabber / XMPP. Все фрагменты можно найти в этой книге http://professionalxmpp.com/, которую я настоятельно рекомендую. Если вы можете каким-либо образом отправить сообщение XMPP после добавления записи в вашу БД, то создать панель управления, которую вы хотите, относительно легко. Вам нужен strophe.js, Jabber / XMPP-сервер (например, ejabberd), http-сервер для проксирования запросов http-bind. Все подробности можно найти в книге. Обязательно прочитайте, и я уверен, что это решит вашу проблему.

...