Jak zaimplementować czat za pomocą Jquery / PHP?

Chcę zaimplementować czat za pomocą PHP / Javascript (Jquery) z funkcjami czatu grupowego i prywatnego.

Problem polega na tym, jak stale aktualizować interfejs w sposób naturalny i ewentualnie także jak pokazywać ' X is typing..'wiadomości na czacie prywatnym.

Oczywistym sposobem wydaje się, że co X sekund/milisekund javascript pingi serwera i pobiera listę nowych wiadomości między ostatnim pingiem i teraz. Jednak może to sprawić, że interfejs wydaje się nieco nienaturalne, jeśli nagle pokój czatu zostanie zalany wiadomościami 5. Wolałbym, żeby każda wiadomość pojawiała się tak, jak jest wpisywana.

Czy istnieje sposób dla javascript, aby utrzymać ciągłe połączenie z serwerem, serwer wypycha wszelkie nowe wiadomości do tego połączenia, a javascript dodaje je do interfejsu, więc pojawiają się jednocześnie, prawie tak szybko, jak serwer je odbiera?

Wiem, że są opcje ankietowe, które wymagają zainstalowania niektórych modułów apache itp, Ale jestem całkiem źle z sysadmin, dlatego wolałbym, aby było bardzo łatwe do zainstalowania rozwiązanie na współdzielonym koncie hostingowym, lub php/mysql tylko rozwiązanie.

Author: Click Upvote, 2010-11-13

10 answers

Czat z PHP / AJAX / JSON

Użyłem tej książki / tutoriala do napisania mojej aplikacji do czatu:

AJAX i PHP: tworzenie responsywnych aplikacji internetowych: Rozdział 5: Ajax chat i JSON .

Pokazuje, jak napisać kompletny skrypt czatu od podstaw.


Comet based chat

Możesz również użyć Comet z PHP.

From: zeitoun :

Comet umożliwia serwerom www wysyłanie danych do klienta bez konieczności jego żądania. W związku z tym, ta technika będzie produkować bardziej responsywne Aplikacje niż klasyczny AJAX. W klasycznych aplikacjach AJAX przeglądarka internetowa (klient) nie może być powiadamiana w czasie rzeczywistym o zmianie modelu danych serwera. Użytkownik musi utworzyć żądanie (na przykład klikając link) lub okresowe żądanie AJAX musi się zdarzyć, aby uzyskać nowe dane z serwera.

Pokażę Ci dwa sposoby implementacji Comet z PHP. Na przykład:

  1. na podstawie ukrytego <iframe> za pomocą znacznika czasu serwera
  2. na podstawie klasycznego żądania nie zwracającego Ajaxu

Pierwszy pokazuje datę serwera w czasie rzeczywistym na klientach, wyświetla mini-chat.

Metoda 1: iframe + server timestamp

Potrzebujesz:

  • skrypt zaplecza PHP do obsługi stałego żądania http backend.php
  • a frondend HTML script load Javascript code index.html
  • prototyp JS biblioteka , ale możesz również użyć jQuery

Skrypt backendu (backend.php) wykona nieskończoną pętlę i zwróci czas serwera tak długo, jak długo klient jest połączony.

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

Skrypt frontend (index.html) tworzy obiekt javascript" comet", który połączy skrypt zaplecza ze znacznikiem kontenera czasu.

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

Metoda 2: Ajax non-return request

Potrzebujesz tego samego co w metodzie 1 + plik dla dataexchange (data.txt)

Teraz backend.php zrobi 2 rzeczy:

  1. zapis do "data.txt " przy wysyłaniu nowych wiadomości
  2. wykonaj nieskończoną pętlę tak długo, jak " data.txt " plik jest niezmieniony
<?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) // check if the data file has been modified
{
    usleep(10000); // sleep 10ms to unload the 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();
?>

Skrypt frontend (index.html) tworzy znaczniki <div id="content"></div>, które będą zawierały wiadomości czatu pochodzące z "data.plik txt", a na koniec tworzy obiekt javascript" comet", który wywoła skrypt zaplecza, aby obserwować nowe wiadomości czatu.

Obiekt comet wyśle żądania AJAX za każdym razem, gdy nowa wiadomość została odebrana i za każdym razem nowa wiadomość jest publikowana. Połączenie stałe jest używane tylko do śledzenia nowych wiadomości. Parametr timestamp url jest używany do identyfikacji ostatniej żądanej wiadomości, tak że serwer powróci tylko wtedy, gdy " dane.txt " znacznik czasu jest nowszy niż znacznik czasu klienta.

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

Alternatywnie

Możesz również spojrzeć na inne aplikacje czatu, aby zobaczyć, jak to zrobili:

 45
Author: Wouter Dorgelo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 21:31:50

Sondaże to nie jest dobry pomysł. Potrzebujesz rozwiązania, które korzysta z długich ankiet lub gniazd internetowych.

Http://hookbox.org jest prawdopodobnie najlepszym narzędziem, jakiego możesz użyć.

Jest to box, który mieszka między serwerem a przeglądarkami i zarządza abstrakcjami nazywanymi kanałami(pomyśl o kanale IRC). Jest to open source na GitHubie: https://github.com/hookbox/hookbox box jest napisany w Pythonie, ale może być łatwo używany z serwerem napisanym w dowolnym języku. To również przyjść z biblioteką Javascript, która jest zbudowana na jsio (wykorzystuje websockets, long-polling, lub cokolwiek jest najlepszą technologią dostępną w przeglądarce), które gwarantują, że wykorzystuje najlepszą technologię dostępną w browsers.In demo widziałem realtime chat zaimplementowany z kilkoma linijkami kodu.

Celem Hookbox jest ułatwienie rozwoju aplikacji internetowych w czasie rzeczywistym, z naciskiem na ścisłą integrację z istniejącą technologią internetową. Mówiąc prościej, Hookbox jest Komunikatem obsługującym sieć Kolejka Przeglądarki mogą bezpośrednio łączyć się z Hookbox, subskrybować nazwane kanały oraz publikować i odbierać wiadomości na tych kanałach w czasie rzeczywistym. Zewnętrzna aplikacja (zazwyczaj sama aplikacja internetowa)może również publikować wiadomości do kanałów za pomocą interfejsu HOOKBOX REST. Wszystkie uwierzytelnianie i autoryzacja jest wykonywana przez zewnętrzną aplikację internetową za pośrednictwem wyznaczonych wywołań zwrotnych "webhook".

alt text

Za każdym razem, gdy użytkownik łączy się lub działa na kanale, (subskrybuj, Opublikuj, Anuluj subskrypcję) Hookbox wysyła żądanie http do aplikacji internetowej w celu autoryzacji akcji. Po subskrybowaniu kanału przeglądarka użytkownika będzie otrzymywać w czasie rzeczywistym zdarzenia, które pochodzą z innej przeglądarki za pośrednictwem interfejsu API javascript lub z aplikacji internetowej za pośrednictwem interfejsu API REST.

Najważniejsze jest to, że cały rozwój aplikacji za pomocą hookbox odbywa się albo w javascript, albo w ojczystym języku samej aplikacji internetowej (np. PHP.)

Potrzebujesz serwer, który może uruchamiać Pythona, ale nie musisz znać Pythona.

Jeśli zamiast tego chcesz używać tylko websockets i PHP to jest dobry punkt wyjścia: http://blancer.com/tutorials/69066/start-using-html5-websockets-today/

 6
Author: Chris Cinelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-24 19:34:59

Sprawdziłeś PHPDaemon , który jest napisany przy aktywnym użyciu libevent i pnctl? It posiada wiele funkcji, a nawet prostą chat aplikację demo. Nawet ma kilka wdrożeń produkcyjnych.

 2
Author: nefo_x,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-14 00:18:05

To może być dobry punkt wyjścia

Http://css-tricks.com/jquery-php-chat/

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-16 16:23:26

Proponuję zaimplementować go z HTML5 WebSockets, z długim polling lub comet jako alternatywa dla starszych przeglądarek. WebSockets otwiera stałe połączenie z przeglądarką. Istnieje open source implementacja php serwera websocket.

 2
Author: Gipsy King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-17 16:08:32

Uważam, że problem, na który patrzysz, wymaga użycia programowania comet web. Więcej szczegółów można znaleźć na Wikipedii, szukając programu Comet, oraz na Ajaxian (jestem jeszcze Nowy na tej stronie i nie mogę zamieścić więcej niż 1 link w odpowiedzi).

Problem polega na tym, że nie można tego łatwo osiągnąć z php po stronie serwera. Więcej szczegółów: using comet with php

Również, jeśli szukasz w google 'PHP comet' znajdziesz tutorial, aby osiągnąć pożądany efekt.

PÓŹNIEJ EDYTUJ

Ape project

Zaimplementowano projekt przy użyciu tego silnika. Świetnie.

Kometa z php

Mam nadzieję, że to pomoże, Gabriel

 1
Author: Gabriel Croitoru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:45:58

Wiem, że jest bardzo późno, ale tutaj

EDIT: Updated link

 1
Author: Aditya Goturu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-11 11:34:53

Nie robiłem tego wcześniej z PHP, ale najlepiej byłoby, gdyby to było jakieś połączenie z gniazdem. Oto Instrukcja PHP dla gniazd.

Nie pamiętam, kto to był tutorial, ale zrobiłem czat jak chcesz używając Flasha dla klienta i Javy dla serwera. Myślę, że TEN link może być tam, gdzie był tutorial i może Ci pomóc.

 0
Author: Aaron Hathaway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-13 20:39:22

Proponuję spróbować Socket.IO wraz z NodeJS . Socket.IO daje ładne i bardzo łatwe API klienta, działa na większości nowoczesnych przeglądarek i używa odpowiedniego transportu, gdzie to możliwe (Websocket, long polling, itp). NodeJS jest demonem po stronie serwera, który obsługuje połączenia HTTP. Oficjalna strona Socket.IO zawiera informacje o tym, jak używać ich razem. Mam nadzieję, że ci pomoże.

 0
Author: galymzhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-16 05:17:59

To wygląda obiecująco! Może być nawet super łatwe do przeróbki:)

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

Ajax chat script w Javascript / PHP

Opis

Ajax Chat jest lekki konfigurowalny Web chat oprogramowanie zaimplementowane w JavaScript i PHP. Skrypt nie wymaga Javy, Flasha ani żadnych innych wtyczek.

Funkcje

    Publiczny i prywatny czat.
  • Zaloguj się jako Zarejestrowanego Użytkownika lub jako gość.
  • Away status, niestandardowe kolory, uśmieszki, płeć użytkownika / ikony statusu.
  • [19]}Czat Ajax może być zintegrowany z zewnętrznym systemem członkowskim poprzez implementację procedury uwierzytelniania użytkowników. Zaawansowane opcje integracji: jeśli użytkownik jest zalogowany na stronie internetowej, może być automatycznie zalogowany na czacie.

Ajax lekki skrypt czatu

*Należy pamiętać, że jest to kopiowanie / wklejanie z oryginalnej strony .

 0
Author: Qwerty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-02 22:34:05