Pull to refresh

Comments 81

интересно. сам сделал нечто подобное, но на другой технологической основе, хотя сервером стоит также nginx. Кстати, посмотрите в сторону специализированного сервера для такого рода проектов — APE Push Engine

Первую проблему решить я пока не придумал как — если вызвать на клиенте в ответ на каждое сообщение какой-то каллбек, который берет идентификатор сообщения и говорит серверу, что все ОК, сообщение получил, то мы получим те же недостатки поллинга — множество запросов к серверу. Хотя можно просто накапливать в буфер это и раз в Х времени посылать массив, что все ОК или если есть недоставка тогда принудительно сбрасывать.

Также у меня принудительно каждые 3 секунды шлется специальный пинг пакет, сообщающий, что сервер работает и клиент может ставить таймер — если в течении N*3 (для верности) не было ни сообщений ни пинга, принудительно перезапустить соединение.
вторая проблема решается на стороне сервера очередью сообщений и упорядочниванием их перед отсылкой.

в IE не работает по причине, что используется дефолтный транспорт XMLHTTPRequest. На javascript.ru было несколько статей про различные методы стрима и кроссбраузерность. также можно посмотреть на исходники клиентской части того же APE
Если вы про второй недостаток (Отсутствие синхронизации исходящих запросов), то я про отсутствие синхронизации исходящих запросов на стороне клиента, проблема решается просто — небольшим воркэраундом над функцией посылки запроса.

Думаю, в jquery функция $.ajax учитывает особенности IE. Причем из IE все сообщения на сервер уходят, только ответа не видно. Такое ощущение, что просто не срабатывает колбэк success
А можно ли добиться гарантированной доставки и без перемешивания? Чтобы сообщения приходили строго в том порядке как они отправляются?
Я бы решил вторую проблему простой нумерацией исходящих сообшений с ID клиента и сесии. Этот же способ поможет решить первую проблему. Для економии траффика цифры можно сжимать.
Гарантированная доставка возможно в случае отправки клиентом подтверждения о доставке нумеровннаых сообщений.

Race condition может быть только в исходящих от клиента запросов. Сообщения с сервера забираются одним запросом, и следующий запрос не будет создан пока не будет получен ответ на предыдущий.
Как вариант лочить отправку новых сообщений, до получения инфы о получении предыдущего?

Не очень понял насчет забора сообщений с сервера. По идее comet рассылает сразу, все, что ему пришло?
1) да, складывать их в очередь ровно также как на сервере
2) да, сразу. после этого сразу посылается следующий запрос, только после окончания предыдущего. то есть в любой момент времени может быть не больше одного читающего с сервера данные запроса. А со стороны клиента в текущей реализации два подряд быстро отправленных сообщения уйдут на сервер в параллельных запросах, и не факт что первое придет раньше :)
Если я правильно понял проблему, то с подобным сталкивался. Если дело не в этом, заранее извиняюсь за коммент не в тему.

Нужно сделать вот так:

jQuery.ajax({
// тут параметры
success: function(rawxml)
{
var xml;
if(jQuery.browser.msie)
{
xml = new ActiveXObject(«Microsoft.XMLDOM»);
xml.async = false;
xml.loadXML(rawxml);
}
else xml = rawxml;
// дальше работаем с XML
Хм, сорри, форматирование кода поплыло :(
Вы бы видели что там творилось)) Опыт показал — Хабру немодерируемый или без кармы чат вреден!
伟大的中华民族已经走过了5000年的文明历程。在古老的中华大地上,勤劳、勇敢、智慧的各族人民共同开拓了幅员辽阔的国土,共同缔造了统一的多民族国家,共同发展了悠久灿烂的中华文化。一部厚重的中国史,就是一部中国各民族诞生、发展、交融并共同缔造统一国家的历史。 从很早的古代起,我国各民族的祖先,就劳动、生息、繁衍在中华大地之上。我们统一的多民族国家,是5000年来特别是秦汉以来的 2000多年里,在各民族长期交往融合中逐步形成和发展的。秦汉时期,不仅基本奠定了以汉族为中心的中原王朝的疆域规模,而且开创了将中华大地上渔猎文明区、游牧文明区和农耕文明区“混而为一”的大一统先河。秦汉陆续在今广西、云南、贵州
Великая китайская нация прошла через 5000 лет цивилизации, конечно. В древней земле Китая, трудолюбивый, мужественный и мудрый народ все сотрудничестве национальности развитие огромных просторах земли и построить единую многоэтнической страны, и общее развитие великолепной китайской культуры. Тяжелой китайской истории, то есть рождение китайских этнических групп, развития, смешения и соучредителя единую нацию. С самого раннего древности, наших предков из различных этнических групп на труд, проценты, размножаются на земле Китая. Мы являемся единой многоэтнической страны, составляет 5000 лет, особенно после Цинь и Хань более чем 2000 лет, интеграции долгосрочный обмен термина в различных этнических группах постепенно формируется и развивается. Цинь и Хань, не только заложила основные центром в Центральной равнины в Хан династии, размеры территории, но и открыл для китайской цивилизации, земля рыболовства и охотничьих угодий, кочевой цивилизации и цивилизованных районов и сельскохозяйственных районов «путать» большой прецедент объединения. Цинь и Хань подряд в этом Гуанси, Юньнань, Гуйчжоу
По-русски «по русски» будет «по-русски».
Так вот кто это был!
Откуда вы знаете, что именно китаец?
А что, не китаец?
Увидели светлые мысли хабражителей :)
сделайте прокрутку в окне пользователей, а то сейчас оно разрослось на два экрана и потянуло за собой строку ввода сообщения
поправил, плюс ещё сделал невозможность разуплотнять окно сообщений :)
в опере всё равно верстка едет (opera 10.10)
В чате какой то срач, даже не обсудить спокойно… Вроде должны бы адекватные люди прийти.
это ведь не часть хабра, это тест приложения, созданного автором.

и да, если ограничивать людей кармой, они будут искать любой способ выплеснуть всё это так чтобы не пострадать)
сколько людей в онлайне? смотрю очень неплохо держит нагрузку.
Сложилось несколько негативное впечатление после посещения данного чата… Тролли флудят длинными сообщениями, из-за которых плывет верстка; гости выпрашивают инвайты…

Интересно, на скольки пользователях в чате он загнется? =)
Думаю загнется он только тогда когда загнется канал… Будет тормозить — можно подрубить EV и установить бэкендом обработки событий kqueue
Чего ему загибаться-то? Нагрузка-то по сути никакая.

Было дело, писал аналогичный функционал на Java.
1000 коннектов держало спокойно, причем это даже в режиме «one thread per client».
Ну да… Тут я согласен с vkramskikh. Хотя канал загнуть — задача не очень выполнимая даже для 1000 флудящих юзеров, а сейчас там и 10 флудеров не наберется…
Зашел и испугался движущейся стены текста.
А строчка # защита от флуда, ограничение на 1 запрос в секунду
limit_req zone=one burst=5 nodelay;
у вас не работает :P
Она работала, но пришлось повысить лимит до 4 запросов в секунду, ибо при плотном потоке сообщений даже long-polling запросы посылаются чаще — этого не предусмотрел… Защиту от флуда надо делать внутри серверной части, nginx тут не спасет.
убрал nodelay и вернул ограничение на 1 запрос в секунду — полегче стало, только сообщения теперь приходят пачками с заметной задержкой. Но это лучше чем стена флуда :)
Эх! А мы думали, что он загибаться начал! :)
нашел более менее сносное решение проблемы флуда, напишу после того как все флудеры уйдут, ибо при знании конфига nginx оно легко обходится :) сообщения теперь можно слать не чаще 1 раза в 6 секунд, а на long-polling соединения это не влияет
Да, стало намного лучше! Только все равно флудить получается. Можно еще сделать блокирование повторных сообщений (достаточно длинных, чтобы «да/нет/угу» не блокировать) :)
Зашел, понаблюдал и понял: ваш сервис — именно то, что было нужно хабру (:
ужас что творится там. я думал хабра это более менее вменяемые люди.
добавьте фильтр флуда. делается всего-то парой условий.
было бы здорово поставить autocomplete=«off»
лагает чат при большом кол-ве сообщений
А я вот хочу прочитать, что же там экраном выше написано, но после каждого нового сообщения в чате — кидает обратно вниз. В данном конкретном чате — не критично, но если пользовать по серьёзному — будет мешать.
А еще заметил, что чат проц грузит довольно сильно: при неактивной вкладке с чатом — 10-30%, при активной — 50-90%…

PS: Celeron 2.66 ггц, 1 гб озу…
Думаю это из-за того, что для добавления сообщений в чат используется сразу несколько обращений к DOM-дереву. В реальном чате так, конечно, делать не надо, здесь это сделано для того чтобы не преобразовывать спецсимволы на серверной стороне
image

Проблем не возникает вообще. Как будто и нет чата.
Всего 300 лишних мегагерц — а какая разница! -))
Надо добавить вывод ip отправителя сообщения.
кто ж такое на перле пишет… erlang батенька надо…
Можно, в принципе, на чем угодно. Это вообще как бы пруф-оф-концепт и на полноценный чат не претендует :) Профит использования эрланга по сравнению с перлом вижу разве что в возможности использования многоядерных процессоров (так как текущая реализация на перле выполняется в один поток)
Можно :) Просто что вы будете делать когда у вас будут тысячи подключений? Профит не только в использовании SMP. Профит в скорости обработки, количестве одновременных подключений и в возможности подключать дополнительные ноды без каких либо проблем
Что буду делать когда будут тысячи подключений? Включу kqueue бэкендом (сейчас там простой select). Серверная часть является FSM, как nginx, и может спокойно выдерживать тысячи подключений. Возможность масштабирования из коробки, вещь, конечно хорошая, но тут особо не нужная. Этот чат висит на дохлой вдске с 256 метрами памяти и 480 мгц проца, плюс на той же вдске хостится сайт с80к хитов в сутки — и ничего, успешно работает :)
я не спорю что nginx примет тысячи подключений. Проблема в другом, сможет ли ваш перловый сервер быстро обработать эти все подключения? или вы столкнетесь с очередью, которая будет отдаваться nginx постепенно. Если так будет, то у вас будут большие таймоуты.
Вы, видимо, меня не поняли :) Мой перловый сервер имеет ровно ту же архитектуру, что и nginx — конечный автомат на асинхронных сокетах, и так же как и nginx, может обрабатывать тысячи подключений (от nginx'а). Причины, по которым я вставил посередине nginx, я описал в статье. В принципе, можно его легко убрать и просто заменить AnyEvent::FCGI на AnyEvent::HTTPD и работать напрямую с клиентом — ничего не изменится. Для вас, наверное, впечатление о перле сложилось в те времена, когда на нем ничего кроме CGI-приложений под веб не делали. Рекомендую почитать мою предыдущую статью, ссылка в этом посте :)
Я вообще стараюсь Perl под веб не юзать :) Скрипты, сбор статистики, генерация репортов — то чем перл выигрывает у всех — а именно работа с текстом.
Просто считаю что для каждой задачи есть свой язык :)
Erlang — это хорошо, но реализация comet есть и на других языках.
Вы пробовали сравнивать разные варианты, например, тот же Orbited на Python?
мне после работы с Zope питон вообще видеть не хочется :)
Оооо… Зопа это феерическая вещь, оправдывающая свое название на 300%!
Я тоже с ней работал, это незабываемо. После этого появляются афоризмы навроде: «Геморрой — это боль в зопе».
Я ее с большой радостью забросил, а питон оставил. Как язык он шикарный, это, можно сказать, «лучик света в большой темной зопе».

На питоне писать очень легко и приятно, он, честно, не виноват, что его использовали для написания такого монстра :)
Нет, не пробовал, ибо:
1) питон я не знаю
2) мне хотелось написать велосипедсвою реализацию, чтобы понять технологию и получить новый опыт

Из готовых решений на перле можно посмотреть Stardust — «the simplest COMET server»
хотел написать про велосипед то что вы хотели написать свою реализацию :)
Хотя это полезно, после этого лучше понимаешь все все это устроено и работает
в чате жесть.

а приватные сообщения там есть?
я осматривал данные технологии, но сходу не придумал как раздавать клиентам идентификаторы или как пихать с сервера сообщения в пул, чтобы некоторые данные слалисль всем юзерам, а некототрые данные слались только определнным юзерам (т.е. весь список мессаг всем, а приватные тоьлко нужным) причем нельзя посылать приватные в общем стеке а потом формировать приватные, иначе умники просто прочитают джсон
В этой реализации нету, но можно их приделать очень просто. Рассылка сообщений всем делается вот так:
Случайно запостил, так вот:
foreach my $user (keys %users) {
push_actions(
$user,
# действия для рассылки
);
}

Для приватного сообщения можно вызвать push_actions не для всех, а только для того, для кого надо :)
а ну да =)

просто у меня задача намного сложнее была… и тогда не придумал как сделать. думал про несколько идентификаторов на одном пользователе
но не суть, вроде пришла в голову светлая мысль =)
Видел, можно будет попробовать воспользоваться
Там в чате такой бодряк теперь :)))
На заметку: причина, по которой ваш чат не работает в IE — неправильная (по мнению IE) кодировка, указанная в заголовке. У вас сейчас возвращается «utf8», а IE поймёт только «utf-8». Немного подробностей: Системная ошибка: -1072896658.
Спасибо! Теперь и в IE работает :)
Тогда сто́ит подправить исходники в посте и замечание о работе в IE.
У нас с друзьями есть реализация комет-чата на Silverlight+WCF.
Если интересно, можем поделится, я думаю.
А вот тут описано как реализовать то же только на ASP.NET
По-моему это стоит инвайта, жаль что я не могу дать.
Sign up to leave a comment.

Articles