Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: + поправка на мультиплексирование
Hello Vitaly,
Мне кажется, если эту задачу можно решить с помощью крона, то не стоит нагружать
ещё и nginx. Лучше максимально упростить интерфейс, и пусть каждый занимается
своим делом. Nginx умеет отдавать данные на множество соединений -- отлично,
вот только этим пусть и занимается. Мы его за это и любим:)
Почитав Ваши сообщения, понял, что упустил в своём драфте саму идею мультиплексирования.
Просто мне самому интереснее не чаты, а персональные потоки сообщений к конкретному
пользователю. Но всё-таки мультиплексирование нужно даже в этом случае --
вдруг юзер откроет два окна, или нужно будет разослать сообщение всем сразу.
Поэтому попробую немного модифицировать схему (надеюсь, это кому-нибудь пригодится):
1) Nginx НЕ передаёт ID соединения бэкенду. Вместо этого бэкенд сам решает,
к какой группе (!) относится данный юзер (на основании авторизационной информации
и т.п.) и возвращает nginx-у список ГРУПП (или их uid-ов), к которым относится
данное соединение. Таблицы соответствий ConnectionID <-> GroupID хранит у
себя сам nginx, это не должно быть особо ресурсоёмко. Чистятся таблицы по
мере отваливания клиентов.
2) При POST-е данных бэкенд указывает список групп, которым предназначен
данный кусок. Все члены групп его получают.
Например, пришёл Вася в чат, соединился. Мы определяем, что он относится
к группам "все", "админы" и "Вася (userid=23243)". Теперь мы можем послать
ему данные, предназначенные а) для всех в чате, б) только для админов и в)
лично для Васи. Причём в группе "Вася (userid=23243)" может быть и больше
одного соединения, юзер имеет право подключиться к чату сколько угодно раз
одновременно.
Недостаток схемы: мы теряем возможность определить на бэкенде, кто из коннектов
отвалился. Но, возможно, это и не нужно -- пусть определяет JS на клиенте
и, если надо, стучит по Аяксу на сервер.
Я тут подумал, если применительно к чатам, было бы неплохо, чтобы
модуль умел скрипт дергать просто так, по таймеру (задается в
конфиге). Как опция - дергал при закрытии любого из подключенных
потоков с передачей ID закрывшегося.
Для чего нужно - например, чтобы сообщать остальным, что пользователь
вышел из чата.
Вроде бы это уровень абстракции порушить не должно. А таймер - в
хозяйстве штука полезная.
DM>> Hello Andrew,
DM>>
DM>> Во-от! В этом-то и состоит нетривиальность задачи:)
DM>>
DM>> Очевидно, единственный способ -- это назначать всем коннектам из
DM>> пула некие id-шники, которые надо а) как-то сообщать бэкенду и б)
DM>> как-то принимать от бэкенда данные именно для этого id.
DM>>
DM>> Навскидку могу предложить примерно такую схему. Nginx (если в
DM>> конфиге включён определённый comet-флаг) передаёт бэкенду вместе с
DM>> запросом и ID соединения (отдельным HTTP-заголовком, скажем
DM>> X-Comet-чтототам). Если бэкенд желает, чтобы данное соединение
DM>> оставалось "висящим", то он в ответе тоже указывает некий
DM>> флаг-заголовок. Тогда nginx, отдав клиенту ответ, не закрывает с
DM>> ним связь (тут нужно, чтобы ответ был "правильным" -- не содержал
DM>> Content-Lenght и т.п.).
DM>>
DM>> Теперь как послать данные нужному клиенту. Создаётся location с
DM>> определённым
DM>> comet-флагом, доступная только для бэкенда. Бэкенд в неё POST-ом в
DM>> любой
DM>> момент может что-то записать, указав, опять-таки, в
DM>> HTTP-заголовке ID клиента-получателя.
DM>> Nginx, если клиент с этим ID-ом ещё не отвалился, пересылает ему
DM>> POST-данные,
DM>> а бэкенду говорит "200 OK". Если же клиент отвалился, то -- 404.
DM>> Ну, естественно, можно и другие варианты придумать. Роль nginx-а
DM>> тут исключительно в поддержании пула коннектов и маршрутизации
DM>> данных между ними.
DM>>
Hello David,
DM>>>> a) дepжит пocтoянныe coeдинeния c клиeнтaми и б) пpинимaeт oт
DM>>>> бэкенда дaнныe и paccылaeт иx в нyжныe coeдинeния.
DM>>>>
как он узнает что в какие-то соединения надо новые данные от
бакендов получить и засунуть ?
--
С уважением
Давид Мзареулян
david@xxxxxxxx
|