Я ищу, чтобы реализовать чат с помощью PHP / Javascript (JQuery) с групповым чатом и частным чатом.
Проблема заключается в том, как естественным образом обновлять интерфейс и, возможно, также показывать сообщения «X is typing ..» в частном чате.
Очевидным способом является то, что каждые X секунд / миллисекунд javascript пингует сервер и выводит список новых сообщений между последним пингом и теперь. Однако это может привести к тому, что интерфейс выглядит немного неестественным, если вдруг в комнате чата наводятся 5 сообщений. Я предпочел бы, чтобы каждое сообщение появлялось, когда оно было напечатано.
Есть ли способ для javascript поддерживать непрерывное соединение с сервером, сервер подталкивает любые новые сообщения к этому соединению, а javascript добавляет их в интерфейс, чтобы они отображались одновременно, почти сразу же, как сервер их получил?
Я знаю, что есть некоторые параметры опроса, которые требуют установки некоторых модулей apache и т. Д., Но я плохо разбираюсь в sysadmin, поэтому я бы предпочел, чтобы было очень простое решение для установки на учетной записи общего хостинга или php / mysql только.
Я использовал эту книгу / учебник для написания своего приложения для чата:
AJAX и PHP: создание адаптивных веб-приложений: глава 5: чат AJAX и JSON .
В нем показано, как писать полный текст с нуля.
Вы также можете использовать Comet с PHP .
От: zeitoun :
Comet позволяет веб-серверам отправлять данные клиенту, не требуя от клиента запроса. Поэтому этот метод будет создавать более гибкие приложения, чем классический AJAX. В классических приложениях AJAX веб-браузер (клиент) не может быть уведомлен в реальном времени о том, что модель данных сервера изменилась. Пользователь должен создать запрос (например, щелкнув ссылку) или периодический запрос AJAX должен произойти, чтобы получить новые данные для сервера.
Я покажу вам два способа реализации кометы с PHP. Например:
<iframe>
использующего временную метку сервера Первая показывает дату сервера в режиме реального времени на клиентах, отображает мини-чат.
Тебе нужно:
backend.php
index.html
backend.php
скрипт ( backend.php
) сделает бесконечный цикл и вернет время сервера, пока клиент подключен.
<?php header("Cache-Control: no-cache, must-revalidate"); header("Expires: Sun, 5 Mar 2012 05:00:00 GMT"); flush(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet php backend</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <script type="text/javascript"> // KHTML browser don't share javascripts between iframes var is_khtml = navigator.appName.match("Konqueror") || navigator.appVersion.match("KHTML"); if (is_khtml) { var prototypejs = document.createElement('script'); prototypejs.setAttribute('type','text/javascript'); prototypejs.setAttribute('src','prototype.js'); var head = document.getElementsByTagName('head'); head[0].appendChild(prototypejs); } // load the comet object var comet = window.parent.comet; </script> <?php while(1) { echo '<script type="text/javascript">'; echo 'comet.printServerTime('.time().');'; echo '</script>'; flush(); // used to send the echoed data to the client sleep(1); // a little break to unload the server CPU } ?> </body> </html>
Скрипт frontend ( index.html
) создает объект javascript «кометы», который свяжет скрипт backend с тегом контейнера времени.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="prototype.js"></script> </head> <body> <div id="content">The server time will be shown here</div> <script type="text/javascript"> var comet = { connection : false, iframediv : false, initialize: function() { if (navigator.appVersion.indexOf("MSIE") != -1) { // For IE browsers comet.connection = new ActiveXObject("htmlfile"); comet.connection.open(); comet.connection.write("<html>"); comet.connection.write("<script>document.domain = '"+document.domain+"'"); comet.connection.write("</html>"); comet.connection.close(); comet.iframediv = comet.connection.createElement("div"); comet.connection.appendChild(comet.iframediv); comet.connection.parentWindow.comet = comet; comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='./backend.php'></iframe>"; } else if (navigator.appVersion.indexOf("KHTML") != -1) { // for KHTML browsers comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); comet.connection.setAttribute('src', './backend.php'); with (comet.connection.style) { position = "absolute"; left = top = "-100px"; height = width = "1px"; visibility = "hidden"; } document.body.appendChild(comet.connection); } else { // For other browser (Firefox...) comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); with (comet.connection.style) { left = top = "-100px"; height = width = "1px"; visibility = "hidden"; display = 'none'; } comet.iframediv = document.createElement('iframe'); comet.iframediv.setAttribute('src', './backend.php'); comet.connection.appendChild(comet.iframediv); document.body.appendChild(comet.connection); } }, // this function will be called from backend.php printServerTime: function (time) { $('content').innerHTML = time; }, onUnload: function() { if (comet.connection) { comet.connection = false; // release the iframe to prevent problems with IE when reloading the page } } } Event.observe(window, "load", comet.initialize); Event.observe(window, "unload", comet.onUnload); </script> </body> </html>
Вам нужно то же самое, что и в методе 1 + файл для dataexchange ( data.txt
)
Теперь backend.php сделает 2 вещи:
<?php $filename = dirname(__FILE__).'/data.txt'; // store new message in the file $msg = isset($_GET['msg']) ? $_GET['msg'] : ''; if ($msg != '') { file_put_contents($filename,$msg); die(); } // infinite loop until the data file is not modified $lastmodif = isset($_GET['timestamp']) ?
$ _GET ['timestamp']: 0; $ currentmodif = filemtime ($ filename); while ($ currentmodif <= $ lastmodif) // проверить, был ли файл данных изменен {usleep (10000); // спать 10 мс, чтобы выгрузить CPU clearstatcache (); $ currentmodif = filemtime ($ filename); }
// return a json array $response = array(); $response['msg'] = file_get_contents($filename); $response['timestamp'] = $currentmodif; echo json_encode($response); flush(); ?>
Скрипт frontend ( index.html
) создает теги <div id="content"></div>
будут содержаться сообщения чата, поступающие из файла data.txt, и, наконец, он создает объект javascript «кометы», который будет вызовите сценарий бэкэнд для просмотра новых сообщений чата.
Объект кометы будет отправлять запросы AJAX каждый раз, когда будет получено новое сообщение, и каждый раз, когда будет отправлено новое сообщение. Постоянное соединение используется только для просмотра новых сообщений. Параметр url timestamp используется для идентификации последнего запрошенного сообщения, так что сервер будет возвращаться только тогда, когда метка времени «data.txt» является более новой, чем временная метка клиента.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="prototype.js"></script> </head> <body> <div id="content"> </div> <p> <form action="" method="get" onsubmit="comet.doRequest($('word').value);$('word').value='';return false;"> <input type="text" name="word" id="word" value="" /> <input type="submit" name="submit" value="Send" /> </form> </p> <script type="text/javascript"> var Comet = Class.create(); Comet.prototype = { timestamp: 0, url: './backend.php', noerror: true, initialize: function() { }, connect: function() { this.ajax = new Ajax.Request(this.url, { method: 'get', parameters: { 'timestamp' : this.timestamp }, onSuccess: function(transport) { // handle the server response var response = transport.responseText.evalJSON(); this.comet.timestamp = response['timestamp']; this.comet.handleResponse(response); this.comet.noerror = true; }, onComplete: function(transport) { // send a new ajax request when this request is finished if (!this.comet.noerror) // if a connection problem occurs, try to reconnect each 5 seconds setTimeout(function(){ comet.connect() }, 5000); else this.comet.connect(); this.comet.noerror = false; } }); this.ajax.comet = this; }, disconnect: function() { }, handleResponse: function(response) { $('content').innerHTML += '<div>' + response['msg'] + '</div>'; }, doRequest: function(request) { new Ajax.Request(this.url, { method: 'get', parameters: { 'msg' : request }); } } var comet = new Comet(); comet.connect(); </script> </body> </html>
Вы также можете посмотреть другие чат-приложения, чтобы посмотреть, как они это сделали:
http://hot-things.net/?q=blite – BlaB! Lite является AJAX и лучше всего просматривается с любой системой чата браузера, которая поддерживает базы данных MySQL, SQLite и PostgreSQL.
Gmail / Facebook Стиль jQuery Chat – этот модуль чата jQuery позволяет вам легко интегрировать чат в стиле Gmail / Facebook на ваш существующий веб-сайт.
Написание JavaScript / PHP Chat Server – учебник
CometChat – CometChat работает на стандартных общих серверах. Требуется только PHP + mySQL.
Опрос – не очень хорошая идея. Вам нужно решение, которое использует длинные опросы или веб-сокеты.
http://hookbox.org , вероятно, лучший инструмент, который вы можете использовать.
Это поле, которое живет между сервером и браузерами и управляет абстракциями, называемыми каналами (подумайте о канале IRC). Он открыт с открытым исходным кодом на github: https://github.com/hookbox/hookbox . Ящик написан на Python, но его можно легко использовать с сервером, написанным на любом языке. Он также поставляется с библиотекой Javascript, которая построена на jsio (использует веб-узлы, длительный опрос или что-то самое лучшее, что доступно в браузере), которые гарантируют, что он использует лучшие технологии, доступные в браузерах. В демо я увидел чат реального времени реализован с несколькими строками кода.
Цель Hookbox – облегчить разработку веб-приложений в реальном времени с акцентом на тесную интеграцию с существующими веб-технологиями. Проще говоря, Hookbox – это очередь сообщений в Интернете. Браузеры могут напрямую подключаться к Hookbox, подписываться на именованные каналы, а также публиковать и получать сообщения по этим каналам в режиме реального времени. Внешнее приложение (как правило, сам веб-приложение) также может публиковать сообщения в каналах с помощью интерфейса REST Hookbox. Вся аутентификация и авторизация выполняются внешним веб-приложением через назначенные обратные вызовы «webhook».
Каждый раз, когда пользователь подключается или работает по каналу, (подписка, публикация, отмена подписки), Hookbox делает HTTP-запрос для веб-приложения для авторизации для действия. После подписки на канал браузер пользователя будет получать события реального времени, которые происходят либо в другом браузере с помощью javascript api, либо из веб-приложения через REST api.
Они имеют ключевое значение в том, что вся разработка приложений с помощью hookbox происходит либо в javascript, либо на родном языке самого веб-приложения (например, PHP).
Вам нужен сервер, который может запускать Python, но вам не нужно знать Python.
Если вместо этого вы хотите использовать только websockets и PHP, это хорошая отправная точка: http://blancer.com/tutorials/69066/start-using-html5-websockets-today/
Вы посмотрели PHPDaemon , который написан с активным использованием libevent и pnctl? Он имеет множество функций и даже простое демонстрационное приложение для чата . Даже у него есть некоторые производственные реализации.
это может быть хорошей отправной точкой
Я предлагаю реализовать его с помощью HTML5 WebSockets, с длинным опросом или кометами в качестве резервного для старых браузеров. WebSockets открывают постоянное соединение с браузером. Существует PHP-версия с открытым исходным кодом сервера websocket .
Я считаю, что проблема, которую вы ищете, требует использования кометного веб-программирования. Вы можете найти более подробную информацию о википедии, найти кометное программирование и Ajaxian (я все еще новичок в этом сайте, и я не могу разместить более 1 ссылки в ответе).
Проблема в том, что это невозможно с помощью php на стороне сервера. Подробнее: использование кометы с php
Кроме того, если вы выполните поиск в google для «php comet», вы найдете учебник для достижения желаемого эффекта.
LATER EDIT
Проект Ape
Реализован проект с использованием этого движка. Отлично.
Комета с php
Надеюсь, это поможет, Габриэль
Я знаю, что это очень поздно, но здесь
EDIT: обновленная ссылка
Я раньше не делал этого с PHP, но лучше всего, вероятно, будет какое-то соединение сокета. Вот руководство PHP для сокетов.
Я не помню, кто это был, но я сделал чат, как то, что вы хотите, используя Flash для клиента и Java для сервера. Я думаю, что эта ссылка может быть там, где был учебник, и это может помочь вам.
Я предлагаю вам попробовать Socket.IO вместе с NodeJS . Socket.IO предоставляет вам приятный и очень простой клиентский API, работает в большинстве современных браузеров и, где это возможно, использует соответствующий транспорт (Websocket, длительный опрос и т. Д.). NodeJS – это серверный демон, который содержит HTTP-соединения. Официальный сайт Socket.IO содержит информацию о том, как использовать их вместе. Надеюсь, это поможет вам.
Это выглядит многообещающе! Могу даже быть супер легким для отдыха 🙂
Ajax Chat – это легкое настраиваемое программное обеспечение для веб-чатов, реализованное в JavaScript и PHP. Скрипт не требует Java, Flash или любых других плагинов.
* Обратите внимание, что это копия / вставка с исходного сайта .