Подтвердить что ты не робот

Как реализовать чат с помощью JQuery/PHP?

Я хочу реализовать чат с помощью PHP/Javascript (JQuery) с групповым чатом и частным чатом.

Проблема заключается в том, как естественным образом обновлять интерфейс и, возможно, также показывать сообщения "X is typing.." в частном чате.

Очевидным способом является то, что каждые X секунд/миллисекунд javascript пингует сервер и выбирает список новых сообщений между последним пингом и теперь. Однако это может привести к тому, что интерфейс выглядит немного неестественным, если вдруг в комнате чата наводятся 5 сообщений. Я предпочел бы, чтобы каждое сообщение появлялось, когда оно было напечатано.

Есть ли способ для javascript для поддержания непрерывного подключения к серверу, сервер подталкивает любые новые сообщения к этому соединению, а javascript добавляет их в интерфейс, чтобы они отображались одновременно, почти сразу же, как сервер их получил?

Я знаю, что есть некоторые параметры опроса, которые требуют установки некоторых модулей apache и т.д., но я плохо разбираюсь в sysadmin, поэтому я бы предпочел, чтобы было очень простое решение для установки в учетной записи общего хостинга, или только для php/mysql.

4b9b3361

Ответ 1

Чат с PHP/AJAX/JSON

Я использовал эту книгу/учебник для написания своего приложения для чата:

AJAX и PHP: создание адаптивных веб-приложений: глава 5: чат AJAX и JSON.

Показывает, как писать полный текст с нуля.


Чат на основе комет

Вы также можете использовать Comet с PHP.

От: zeitoun:

Comet позволяет веб-серверам отправлять данные клиенту, не требуя от клиента запроса. Поэтому этот метод будет создавать более гибкие приложения, чем классический AJAX. В классических приложениях AJAX веб-браузер (клиент) не может быть уведомлен в реальном времени о том, что модель данных сервера изменилась. Пользователь должен создать запрос (например, щелкнув ссылку) или периодический запрос AJAX должен произойти, чтобы получить новые данные для сервера.

Я покажу вам два способа реализации кометы с PHP. Например:

  • на основе скрытого <iframe> с использованием отметки времени сервера
  • на основе классического невозвратного запроса AJAX

Первый показывает дату сервера в режиме реального времени на клиентах, отображает мини-чат.

Способ 1: временная метка iframe + server

Вам нужно:

  • backend PHP script для обработки постоянного HTTP-запроса backend.php
  • frondend HTML script загрузить Javascript code index.html
  • прототип JS-библиотеки, но вы также можете использовать jQuery

Бэкэнд script (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>

Интерфейс script (index.html) создает объект javascript "кометы", который соединяет бэкэнд script с тегом контейнера времени.

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

Способ 2: Невозвратный запрос AJAX

Вам нужно то же самое, что и в методе 1 + файл для обмена данными (data.txt)

Теперь backend.php сделает 2 вещи:

  • Записать в "data.txt" при отправке новых сообщений
  • Выполняйте бесконечный цикл, пока файл "data.txt" не изменяется
<?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();
?>

Интерфейс script (index.html) создает теги <div id="content"></div>, в котором будут содержаться сообщения чата, поступающие из файла data.txt, и, наконец, он создает объект javascript "кометы", который будет вызывать бэкэнд script для просмотра новых сообщений чата.

Объект кометы будет отправлять запросы 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 Style jQuery Chat - Этот модуль чата jQuery позволяет вам легко интегрировать чат стиля Gmail/Facebook в существующие сайт.

  • Написание JavaScript/PHP Chat Server - Учебник

  • CometChat - CometChat работает на стандартных общих серверах. Требуется только PHP + mySQL.

Ответ 2

Опрос - это не очень хорошая идея. Вам нужно решение, которое использует длинные опросы или веб-сокеты.

http://hookbox.org - лучший инструмент, который вы можете использовать.

Это поле, которое живет между сервером и браузерами и управляет абстракциями, называемыми каналами (подумайте о канале IRC). С открытым исходным кодом на github: https://github.com/hookbox/hookbox Ящик написан на Python, но его можно легко использовать с сервером, написанным на любом языке. Он также поставляется с библиотекой Javascript, которая построена на jsio (использует веб-узлы, длительный опрос или что-то самое лучшее, что доступно в браузере), которые гарантируют, что он использует лучшие технологии, доступные в браузерах. В демо я увидел чат реального времени реализован с несколькими строками кода.

Цель Hookboxs - облегчить разработку веб-приложений в режиме реального времени, делая упор на тесную интеграцию с существующими веб-технологиями. Проще говоря, Hookbox - это очередь сообщений в Интернете. Браузеры могут напрямую подключаться к Hookbox, подписываться на именованные каналы, а также публиковать и получать сообщения по этим каналам в режиме реального времени. Внешнее приложение (как правило, сам веб-приложение) также может публиковать сообщения в каналах с помощью интерфейса REST Hookbox. Вся аутентификация и авторизация выполняются внешним веб-приложением через назначенные обратные вызовы "webhook".

alt text

Каждый раз, когда пользователь подключается или работает по каналу, (подписываться, публиковать, отписываться), Hookbox делает HTTP-запрос веб-приложению для авторизации для действия. После подписки на канал браузер пользователей будет получать события реального времени, которые происходят в другом браузере через api javascript или из веб-приложения через REST api.

Они понимают, что вся разработка приложений с помощью hookbox происходит либо в javascript, либо на родном языке самого веб-приложения (например, PHP.)

Вам нужен сервер, который может запускать Python, но вам не нужно знать Python.

Если вместо этого вы хотите использовать только websockets и PHP, это хорошая отправная точка: http://blancer.com/tutorials/69066/start-using-html5-websockets-today/

Ответ 5

Я предлагаю реализовать его с помощью HTML5 WebSockets, с длинным опросом или кометами в качестве резервного для старых браузеров. WebSockets открывают постоянное соединение с браузером. Существует открытый php-реализация сервера websocket.

Ответ 6

Я считаю, что проблема, которую вы ищете, требует использования кометного веб-программирования. Вы можете найти более подробную информацию о википедии, найти кометное программирование и Ajaxian (я все еще новичок в этом сайте, и я не могу разместить более 1 ссылки в ответе).

Проблема в том, что это невозможно с помощью php на стороне сервера. Подробнее: с использованием кометы с php

Кроме того, если вы ищете в google для 'php comet', вы найдете учебник для достижения желаемого эффекта.

LATER EDIT

Проект Ape

Реализован проект с использованием этого движка. Замечательно.

Комета с php

Надеюсь, это поможет, Габриэль

Ответ 7

Я знаю, что это очень поздно, но здесь

EDIT: обновленная ссылка

Ответ 8

Я раньше не делал этого с PHP, но лучше всего, скорее всего, это какое-то соединение сокета. Здесь руководство PHP для сокетов.

Я не помню, кто это был, но я сделал чат-комнату, как то, что вы хотите, используя Flash для клиента и Java для сервера. Я думаю, эта ссылка может быть там, где было урок, и это может помочь вам.

Ответ 9

Я предлагаю вам попробовать Socket.IO вместе с NodeJS. Socket.IO предоставляет вам приятный и очень простой клиентский API, работает в большинстве современных браузеров и, где это возможно, использует соответствующий транспорт (Websocket, длительный опрос и т.д.). NodeJS - это серверный демон, который содержит HTTP-соединения. Официальный сайт Socket.IO содержит информацию о том, как использовать их вместе. Надеюсь, это поможет вам.

Ответ 10

Это выглядит многообещающим! Может быть, даже супер легко переделать:)

http://www.php-development.ru/javascripts/ajax-chat.php

Ajax Chat script в Javascript/PHP

Описание

Ajax Chat - это легкое настраиваемое программное обеспечение для веб-чата, реализованное в JavaScript и PHP. script не требует Java, Flash или других плагинов.

Особенности

  • Общественный и частный чат.
  • Войти как зарегистрированный пользователь или в качестве гостя.
  • Статус выхода, пользовательские цвета, смайлики, значки пользователя/состояния пользователя.
  • Ajax Chat может быть интегрирован с сторонней системой членства, реализуя процедуру аутентификации пользователей. Расширенные возможности интеграции: если пользователь зашел на сайт, он может автоматически войти в чат.

Ajax lightweight chat script

* Обратите внимание, что это копия/вставка из исходного сайта.