Приложение чата AJAX опрос - PullRequest
14 голосов
/ 30 августа 2008

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

Некоторые участники проекта предположили, что мы можем использовать XMPP через BOSH, я сказал, что это похоже на попытку поймать рыбу с помощью лодки, и предложил более простой метод, такой как простой веб-чат Ajax / MySQL, но мы обеспокоены о снижении производительности на сервере из-за постоянного опроса множества открытых одновременно чатов.

Кто-нибудь делал что-то подобное раньше? Чтобы вы посоветовали?

Ответы [ 12 ]

7 голосов
/ 30 августа 2008

Вы также можете посмотреть на Комету .

Используется GTalk, Meebo и многими другими приложениями чата . Несколько лет назад, когда я экспериментировал с ним, было не так много библиотек или подробностей о серверной архитектуре для его реализации, но, похоже, сейчас гораздо больше вещей.

Посмотрите на проект cometd для получения дополнительной технической информации.

5 голосов
/ 30 августа 2008

Что бы вы порекомендовали?

XMPP через BOSH

Нет необходимости изобретать свой собственный формат сообщения и транспортный протокол, когда кто-то другой имеет. Если вы попробуете, он постепенно станет таким же сложным, как BOSH, но без поддержки сторонней библиотеки или стандартизации.

3 голосов
/ 21 сентября 2008

Если вам не нравится идея HTTP-опроса, у вас может быть Flash-фильм на странице чата, который имеет постоянное соединение с каким-нибудь демоном на сервере, тогда Flash-фильм будет вызывать функции JavaScript на клиент для обновления чата по мере поступления новых сообщений. (Если вы не хотите Flash интерфейс для вашего чата ..)

2 голосов
/ 21 сентября 2008

Существует очень хороший сервер для обработки отправки сообщений с сервера в браузер (дублирован Comet ) - Orbited Он легко интегрируется с другими технологиями (Django, Rails, PHP и т. Д.), Как и memcached.

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

2 голосов
/ 30 августа 2008

Возможно, вы захотите заглянуть в комету.

Я думал, что все использовали Cometd для такого рода вещей.

BOSH - это стандарт для передачи XMPP через HTTP. Для передачи данных клиенту используется Comet.

1 голос
/ 21 сентября 2008

Хитрость заключается в том, чтобы понять, что единственное время, когда ваше приложение должно вызывать CGI на сервере, - это когда кто-то что-то говорит. Для регулярных опросов опрашивайте статическую страницу, которую ваш CGI-скрипт обновляет при каждом новом чате. Используйте запросы HEAD, сравнивайте временные метки с последними, и выполняйте полный GET только при их изменении. У меня есть простое наивное приложение для чата, реализованное таким образом, и загрузка и использование полосы пропускания незначительны для нескольких десятков одновременных пользователей.

1 голос
/ 30 августа 2008

Я делал то же самое несколько месяцев назад и получал удовольствие, просто играя с концепциями. На самом деле я использовал метод forever-frame вместо опроса.

Приведенный ниже код - это мой js-файл "кометы", в котором содержатся общие понятия, необходимые для настройки "party chat".

function Comet(key) {

  var random = key;
  var title = 'Comet';
  var connection = false;
  var iframediv = false;
  var browserIsIE = /*@cc_on!@*/false;
  var blurStatus = false;
  var tmpframe = document.createElement('iframe');
  var nl = '\r\n';

  this.initialize = function() {
    if (browserIsIE) {
      connection = new ActiveXObject("htmlfile");
      connection.open();
      connection.write("<html>");
      connection.write("<script>document.domain = '"+document.domain+"'");
      connection.write("</html>");
      connection.close();
      iframediv = connection.createElement("div");
      connection.appendChild(iframediv);
      connection.parentWindow.comet = comet;
      iframediv.innerHTML = "<iframe id='comet_iframe' src='./comet.aspx?key="+random+"'></iframe>";
    } else {
      connection = document.createElement('iframe');
      connection.setAttribute('id', 'comet_iframe');
      iframediv = document.createElement('iframe');
      iframediv.setAttribute('src', './comet.aspx?key='+random);
      connection.appendChild(iframediv);
      document.body.appendChild(connection);
    }
  }

  // this function is called from the server to keep the connection alive
  this.keepAlive = function () {
    if (!browserIsIE) {
        mozillaHack();
    }
  }

  // this function is called from the server to update the client
  this.updateClient = function (value) {
    var outputDiv = document.getElementById('output');
    outputDiv.value = value + nl + outputDiv.value;
    if (blurStatus == true) {
        document.title = value;
    }
    if (!browserIsIE) {
        mozillaHack();
    }
  }

  this.onUnload = function() {
    if (connection) {
      // this will release the iframe to prevent problems with IE when reloading the page
      connection = false;
    }
  }

  this.toggleBlurStatus = function(bool) {
    blurStatus = bool;
  }

  this.resetTitle = function() {
    document.title = title;
  }

  function mozillaHack() {
    // this hack will fix the hour glass and loading status for Mozilla browsers
    document.body.appendChild(tmpframe);
    document.body.removeChild(tmpframe);
  }
}
0 голосов
/ 14 сентября 2012

Я только что нашел этот пост, он старый, но концепция опроса создает проблемы для многих людей. Так что я приведу пример реализации здесь. Но прежде чем дать его вам, я должен дать вам совет, который некоторое время назад меня бесил:

При опросе вы должны позаботиться о поведении сессий ( условия гонки ). Для простоты: если вы открываете сеанс, файл сеанса блокируется до тех пор, пока сеанс не будет закрыт, чтобы избежать двух записей, записывающих в него разные данные. Поэтому, если вам нужен сеанс, чтобы проверить, вошел ли пользователь в систему или около того, всегда закрывайте сеанс перед опросом.

В моей демонстрации приведен пример реализации опроса в PHP. Я не буду использовать базу данных, но файл вместо этого. Когда вы нажмете кнопку опроса, вы войдете в цикл, и пока файл не будет изменен, вы будете продолжать опрос. Когда вы заполните форму и нажмете «Отпустить», то, что вы набрали, будет сохранено в файл. Время изменения файла изменится, поэтому опрос будет остановлен.

Совет: используйте инструмент, подобный Firebug , чтобы увидеть, что происходит.

Теперь давайте поговорим лучше, чем мой английский:

<?php

    // For this demo
    if (file_exists('poll.txt') == false) {
        file_put_contents('poll.txt', '');
    }

    if (isset($_GET['poll'])) {

        // Don't forget to change the default time limit
        set_time_limit(120);

        date_default_timezone_set('Europe/Paris');
        $time = time();

        // We loop until you click on the "release" button...
        $poll = true;
        $number_of_tries = 1;
        while ($poll)
        {
            // Here we simulate a request (last mtime of file could be a creation/update_date field on a base)
            clearstatcache();
            $mtime = filemtime('poll.txt');

            if ($mtime > $time) {
                $result = htmlentities(file_get_contents('poll.txt'));
                $poll = false;
            }

            // Of course, else your polling will kill your resources!
            $number_of_tries++;
            sleep(1);
        }

        // Outputs result
        echo "Number of tries : {$number_of_tries}<br/>{$result}";
        die();
    }

    // Here we catch the release form
    if (isset($_GET['release']))
    {
        $data = '';
        if (isset($_GET['data'])) {
            $data = $_GET['data'];
        }
        file_put_contents('poll.txt', $data);
        die();
    }

?>

<!-- click this button to begin long-polling -->
<input id="poll" type="button" value="Click me to start polling" />

<br/><br/>

Give me some text here :
<br/>
<input id="data" type="text" />
<br/>

<!-- click this button to release long-polling -->
<input id="release" type="button" value="Click me to release polling" disabled="disabled" />

<br/><br/>

Result after releasing polling :
<div id="result"></div>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">

// Script to launch polling
$('#poll').click(function() {
    $('#poll').attr('disabled', 'disabled');
    $('#release').removeAttr('disabled');
    $.ajax({
        url: 'poll.php',
        data: {
            poll: 'yes' // sets our $_GET['poll']
        },
        success: function(data) {
            $('#result').html(data);
            $('#poll').removeAttr('disabled');
            $('#release').attr('disabled', 'disabled');
        }
    });
});

// Script to release polling
$('#release').click(function() {
    $.ajax({
        url: 'poll.php',
        data: {
            release: 'yes', // sets our $_GET['release']
            data: $('#data').val() // sets our $_GET['data']
        }
    });
});

</script>

Вы можете попробовать это здесь

0 голосов
/ 06 мая 2009

Оформить заказ Speeqe . Это решение с открытым исходным кодом для сетевых чатов, использующее BOSH и XMPP за кулисами.

0 голосов
/ 21 сентября 2008

Я думаю, что опрос - это самый простой подход, и я бы рекомендовал его сначала. Если нагрузка становится проблемой, начинайте изучать более сложные методы. Хорошая дискуссия о плюсах и минусах здесь - http://www.infoq.com/news/2007/07/pushvspull
http://ajaxian.com/archives/a-report-on-push-versus-pull

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