Pull to refresh

Comments 19

Мы уже несколько месяцев используем centrifugо в продакшне, полет нормальный, в онлайне сейчас порядка 10-20 тысяч пользователей.
Одна из проблем, с которой столкнулись — sharing вебсокет подключения между вкладками (так как обычно наши пользователи открывают много вкладок одновременно, плодить столько же подключений смысла нет). Мы используем crosstab.js, но он временами работает кривовато и иногда теряет связь между табами. Вы с таким сталкивались? Что-то используете для этого?
Приятно слышать! Да, к сожалению, вебсокеты работают именно так — было бы здорово иметь возможность нативным способом мультиплексировать соединения в одно, но пока ее нет. Поэтому и возникают мысли про особенности HTTP/2 – если в вашем случае большое кол-во соединений из разных вкладок это проблема, то возможно стоит посмотреть в сторону использования HTTP-транспортов SockJS вкупе с HTTP/2 сервером? Центрифуга научится HTTP/2 в ближайшее время — как только Go 1.6.1 зарелизится — собственно транспорты вроде eventsource должны будут работать через одно соединение из разных вкладок. Возможно, что за последним Nginx-ом уже сейчас можно по HTTP/2 с Центрифугой общаться — но я пока не пробовал. Кстати, надеюсь, что в какой-то момент в будущем Centrifugo постепенно уйдет от SockJS, но это пока не скоро. Мы у себя crosstab и аналогичные решения не пробовали, потому что проблемы такой пока не стояло.
> было бы здорово иметь возможность нативным способом мультиплексировать соединения в одно, но пока ее нет.

Ну с натягом можно назвать shared workers такой нативной возможностью. Для большинства посетителей работает. Остальные могут плодить по отдельному подключению на вкладку, благо их не так много будет.

Однако Центрифуга требует вот такого шаманства:

var window = self;
importScripts("/centrifugo.js");

Иначе не может вроде даже в консольку писать. SockJS например такого не требует, и даже теряет работоспособность. Поэтому приходится загружать сначала все скрипты, а Центрифугу в самом конце сотворив вот это колдунство.

Скажите пожалуйста, а пуш в Service Workers планируется сделать? А то своими силами я это реализовать не могу, а хочется отправлять сообщеньки даже если сайт не открыт, как тот же Фейсбук делает.

Ещё вопросик, пользуясь случаем, т.к.карма низкая, писать могу редко. Можно ли научить Центрифугу для вызовов API слушать не только TCP порт, но и просто unix socket? Возможно это несложно реализуется через какую-нить готовую библиотеку.

Спасибо за вашу штуку! Она волшебная и исцеляющая! Реально. Пользоваться очень удобно.
Спасибо! Видимо я вам в ЛС напишу, чтобы получше разобраться с shared worker'ами – так с ходу и сказать нечего, потому что не сталкивался до этого и не до конца пока понимаю.
Пуш в Service Workers планируем, да — но только когда примут общий драфт для браузеров, чтобы не завязываться только на Хром и GCM, вот issue уже стоит. Но когда примут драфт пока не ясно.
Про unix socket: в Go функция ListenAndServe, которая запускает HTTP-сервер, слушает tcp адрес, поэтому я не могу утверждать, что если логику этой функции вынести в проект и использовать unix-сокет все будет корректно работать.
А что критичного для вас в go 1.6.1, что не позволяет использовать http/2 сервер на 1.6?
Мы пока лишь http/2 клиент используем из 1.6, так что интересно.
Я думаю, что в случае Центрифуги ничего особо не держит, просто привычка дожидаться минорных версий с фиксами проблем, обнаруженных в релизе. Вообще, я думал к публикации статьи уже будет 1.6.1, но уже на 19 дней milestone 1.6.1 просрочен. Еще с 1.6 были проблемы у sockjs-go — если бы поспешил, то пропустил бы это в релиз.
Ожидание миноров это да, это очень хорошо. Но в случае http/2 пришлось, хоть и не без проблем, пересесть на 1.6, чтобы APNS обновить.
Возможно, как вариант, можно было использовать golang.org/x/net/http2, как, например, вот тут
Он и используется) Но на 1.5 с ним не работает timeout + (и на 1.6) есть проблема с получение GOAWAY и SETTINGS фреймов. Пришлось патчить чуть-чуть.
pavel_d после комментария от igordata и небольшого обсуждения в ЛС судя по всему SharedWorker – вполне себе путь работать через одно вебсокет-соединение. Всю работу с Центрифугой можно возложить на воркер, который будет рассылать полученные сообщения табам. Но тут мне самому предстоит покопаться прежде чем что-то дополнительно смогу сказать.
Можете рассказать как реализована привязка сессии браузера к бэкенду, пример: Бэкенд на PHP, а работа с фронтедом через centrifugо.
Я так понимаю это из серии StickySession?
P.S: centrifugo.herokuapp.com — не работает, при вводе пароля:
POST centrifugo.herokuapp.com/auth 400 (Bad Request)
Привязка сессии пользователя к бэкенду никак не затрагивается в такой схеме. Для вас пользователь остается точно таким же как был до этого — просто теперь он еще соединен дополнительным постоянным коннектом с Центрифугой, от которой будет получать новые сообщения, отправленные вами с бэкенда в Центрифугу. Например, пользователь совершает какое-либо действие на сайте — пусть это будет добавление нового комментария. При этом этот комментарий вы отправляете на ваш бэкенд как и всегда — обычным или AJAX POST запросом. Соответственно при этом на бэкенд прилетает стандартный запрос от пользователя (который определяется вашим бэкендом стандартным для PHP способом). После валидации и сохранения комментария — отправляете его в нужный канал. Главное правильно организовать каналы. В моем понимании sticky sessions — это проксирование запросов клиентов на один и тот же инстанс бэкенда, поэтому возможно я не до конца понял вопрос и ответил не на него:)
У меня демо инстанс работает и пароль (demo) подходит, в 3 браузерах проверил на всякий случай — может, опечатались?
Да демо работает, извиняюсь.
Вопрос вот в чем, как послать сообщение конкретному пользователю?
В socket.io предлагают хранить все коннекты пользователей, у вас я так понял это через Redis сделано.
Пользователь подписывается на канал personal_messages#2456 — где 2456 это ID пользователя (решетка это спец символ в Центрифуге, который запрещает другим юзерам подписываться на этот канал, в принципе можно и без нее обойтись — просто personal_messages2456, но обычно на персональные каналы другим подписываться не дают). Соответственно на бэкенде вы название этого канала для юзера знаете и отправляете сообщение в него. Redis тут никак не участвует (Центрифугу можно запустить и без Редиса — более того по умолчанию Redis не используется).
То есть, пользователь со стороны клиента (браузера), авторизуется согласно:
https://fzambia.gitbooks.io/centrifugal/content/mixed/private_channels.html
А дальше подписывается на определнный канал (свой), и через бэкенд можно слать сообщения именно в тот канал, правильно я понимаю?
Тогда слещующий вопрос, как достоверно сказать что тот пользователь что авторизуется и подписывается на канал, есть настоящий пользователь, грубо говоря что мне мешает послать любой UserId и подписаться на его приватный канал?
Не совсем так — приватные каналы и каналы с решеткой немного разные вещи. При подписке на приватный канал на ваш бэкенд отправляется дополнительный AJAX запрос от клиента Центрифуги — чтобы ваш бекенд вернул подпись (на основе секретного ключа который знают только Центрифуга и ваш бэкенд), разрешающую клиенту подписку на этот канал. Каналы с решеткой позволяют этого лишнего запроса на бэкенд избежать. UserID при подключении также подтверждается HMAC SHA-256 токеном на основе секретного ключика, который вы генерите на бэкенде, валидный токен говорит Центрифуге о том, что при подключении был передан корректный UserID. Поэтому пока этот ключ не известен чужой UserID вы не передадите. В этой статье я про это не писал, потому что это было в предыдущих. Но вообще обо всех параметрах и подписях лучше начинать смотреть вот отсюда .
FZambia почему большой упор на Redis и именно на push? Хотелось бы иметь возможность полноценно и получать данные от клиента, так сказать в полной мере ощутить прелести полнодуплексного протокола Websocket.

А модель доставки было бы удобно выбирать в зависимости от потребностей, например если внедрить RabbitMQ.
Wadik привет! Упор на PUSH вытекает из концепта Центрифуги — логика приложения остается в приложении — проверка прав, сохранение данных и т.д. Это позволяет Центрифуге работать в связке с бекендом на любом языке.

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

Redis используется для некоторых фич — таких как presence и кеш сообщений в каналах. По большому счету внутри Центрифуги жесткой привязки к Редису нет. Я сейчас делаю рефакторинг, который в теории позволит использовать любой PUB/SUB провайдер и любую бд для presence/history данных. Но это потребует написания кода, который все это будет имплементировать. Для Редиса этот код уже есть, соответственно.
Спасибо за исчерпывающий ответ и за Центрифугу! Надеюсь получится найти применение в своих предстоящих проектах.
Sign up to leave a comment.