Приложение для чата AJAX Polling
В проекте, над которым я сейчас работаю, нам нужно разработать приложение для веб-чата, а не очень сложный чат, просто способ соединить двух человек, чтобы поговорить на очень конкретную тему, нам не нужна какая-либо аутентификация для одного из двух пользователей нам не нужно поддерживать смайлики, аватары или тому подобное.
Некоторые участники проекта предложили использовать XMPP через BOSH, я сказал, что это все равно что пытаться поймать рыбу с помощью лодочной сети, и предложил более простой метод, такой как простой веб-чат Ajax/MySQL, но мы беспокоимся о производительности. попадание на сервер из-за постоянного опроса множества открытых одновременно чатов.
Кто-нибудь делал что-то подобное раньше? Чтобы вы посоветовали?
Ответы
Ответ 1
Вы также можете посмотреть на комету.
Он используется GTalk, Meebo и многими другими приложениями чата. Несколько лет назад, когда я экспериментировал с ним, было не так много библиотек или деталей о серверной архитектуре для его реализации, но, похоже, сейчас есть намного больше вещей.
Посмотрите на проект Cometd для получения дополнительной технической информации.
Ответ 2
Что бы вы порекомендовали?
XMPP через BOSH
Не нужно изобретать свой собственный формат сообщения и транспортный протокол, если у кого-то еще есть. Если вы попытаетесь, он будет медленно расти настолько же сложно, как BOSH, но без поддержки сторонней библиотеки или стандартизации.
Ответ 3
Если вам не нравится идея HTTP-опроса, у вас может быть Flash-фильм на странице чата с постоянным подключением к некоторому деамону на сервере, тогда Flash-фильм будет вызывать функции JavaScript на клиент для обновления чата при появлении новых сообщений. (Если вам не нужен интерфейс Flash для вашего чата.)
Ответ 4
Вы также можете посмотреть в комету.
Я думал, что все используют комет для такого рода вещей.
BOSH - это стандарт для транспортировки XMPP через HTTP. Он включает комет для передачи данных клиенту.
Ответ 5
Существует очень хороший сервер для обработки нажатия сообщения от сервера к браузеру (дублируется Comet) - Orbited. Он легко интегрируется с другими технологиями (Django, Rails, PHP и т.д.), Так же как memcached.
Вам действительно нужно проверить это, если вы хотите справиться с серьезной нагрузкой. В противном случае простой Ajax-опрос - лучший способ.
Ответ 6
Я сделал то же самое несколько месяцев назад и повеселился, просто играя с концепциями. Я фактически использовал метод forever-frame вместо опроса.
Ниже приведен код js файла "кометы", который содержит общие понятия, необходимые для настройки "партийного чата".
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);
}
}
Ответ 7
Трюк заключается в том, чтобы понять, что единственный раз, когда ваше приложение должно вызывать CGI на сервере, - это когда кто-то что-то говорит. Для регулярных опросов опросите статическую страницу, обновляющую ваш CGI script всякий раз, когда появляется новый чат. Используйте HEAD-запросы, сравнивайте отметки времени с теми, которые были замечены в последний раз, и выполняйте только GET, когда они меняются. У меня есть приложение простого наивного чата, реализованное таким образом, а загрузка и использование полосы пропускания незначительны для нескольких десятков одновременных пользователей, которые у нас есть.
Ответ 8
Я думал, что все используют комет для такого рода вещей.
Ответ 9
Я согласен с Джоном. Но был еще один вопрос, на который не ответил.
Я сделал это, но вместо того, чтобы использовать базу данных, мы использовали плоский файл, но в конечном итоге он испортил сервер, но только когда у нас было ~ 450 активных пользователей, и если бы мы сделали это с базой данных, это, вероятно, лучше.
Это было сделано на основной учетной записи хостинга от Godaddy.
Edit: BTW Godaddy звучал меньше, чем забавлялся, когда я получил телефонный звонок.
Ответ 10
Я думаю, что опрос - это самый простой подход, и он порекомендовал бы это в первую очередь. Если загрузка становится проблемой, она рассматривает более сложные методы.
Хорошая дискуссия о плюсах и минусах здесь -
http://www.infoq.com/news/2007/07/pushvspull
http://ajaxian.com/archives/a-report-on-push-versus-pull
Ответ 11
Оформить заказ Speeqe. Его с открытым исходным кодом для веб-чатов, в которых используются BOSH и XMPP за кулисами.
Ответ 12
Я только что нашел этот пост, он старый, но концепция опроса дает проблемы для большого количества 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>
Вы можете попробовать здесь