Опрос Ajax

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

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

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

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

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

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

Чтобы вы посоветовали?

XMPP через BOSH

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

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

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

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

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

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

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

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

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

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

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); } } 

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

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

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

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

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

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

Когда вы проводите опрос, вы должны следить за поведением сеансов ( условиями гонки ). Чтобы сделать его простым: если вы открываете сеанс, файл сеанса блокируется до тех пор, пока сеанс не будет закрыт, чтобы избежать того, чтобы 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> 

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