2008-08-30 7 views
13

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

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

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

ответ

6

Возможно, вы также захотите изучить Comet.

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

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

5

Что вы посоветуете?

XMPP через BOSH

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

0

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

2

Возможно, вы также захотите изучить Комету.

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

BOSH - это стандарт для транспортировки XMPP через HTTP. Он включает комет для передачи данных клиенту.

1

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

Этот код является моим java-файлом «кометы», который содержит общие понятия, необходимые для настройки «партийного чата».

function Comet(key) { 

    var random = key; 
    var title = 'Comet'; 
    var connection = false; 
    var iframediv = false; 
    var browserIsIE = /*@[email protected]*/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

эта техника rquired иметь кот добавить на третьем-на кометной библиотеке ..etc? или может служить на типичном сервлете? есть ли какое-нибудь демо/рабочее приложение, на которое мы можем ссылаться? – cometta 2009-09-01 09:42:43

0

Я согласен с Джоном. Но был еще один вопрос, на который не ответил.
Я сделал это, но вместо того, чтобы использовать базу данных, мы использовали плоский файл, но в конечном итоге он испортил сервер, но только когда у нас было ~ 450 активных пользователей, и если бы мы сделали это с базой данных, это, вероятно, лучше жить.
Это было сделано на основе учетной записи хостинга от Godaddy.

Редактировать: BTW Godaddy звучал меньше, чем забавлялся, когда я получил телефонный звонок.

0

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

2

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

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

1

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

3

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

0

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

Когда вы проводите опрос, вы должны позаботиться о поведении сеансов (race conditions). Чтобы сделать его простым: если вы открываете сеанс, файл сеанса блокируется до тех пор, пока сеанс не будет закрыт, чтобы избежать того, чтобы 2 адаса вносили в него разные данные. Итак, если вам нужен сеанс, чтобы проверить, зарегистрирован ли пользователь или нет, всегда закрывайте сеанс перед опросом.

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

Совет: используйте инструмент, например 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> 

Вы можете попробовать это here

Смежные вопросы