Pull to refresh

Comments 137

> Продвинутые технологии в основе этой схемы позволяют сильно упростить процесс и сосредоточиться на логике самой работы.

У меня только один вопрос. Почему нагромождение технологий друг на друга называется «упростить процесс»?

Это вы называете нагромождением технологий? Это совершенно минимальный джентльменский набор риалтаймового проекта. Попробуйте решить эту задачу меньшим количеством. Вы бы знали, что во всяких фейсбуках происходит, вот где нагромождение.

А упрощение это потому, что непосредственно кода стало в несколько раз меньше, а работает всё эффективнее и производительнее.
> Это вы называете нагромождением технологий?

Итак. У вас уже есть сайт на РНР. Вам нужно решить какую-то задачу. Вы почему-то взять node.js (хотя работа с вебсокетами в PHP более, чем возможна). ВНЕЗАПНО оказалось, что надо еще каким-то образом общаться между node.js и PHP. Правильно, давайте навернем еще сверху pubsub через редис.

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

> Это совершенно минимальный джентльменский набор риалтаймового проекта.

Hype Driven Development во всей красе.
Технологии удобного событийно-ориентированного программирования на php — в студию, пожалуйста. А также было бы интересно услышать о том, как можно общаться между различными php-процессами (отправляющими и принимающими сообщения) без какой-либо общей среды вроде redis.
> Технологии удобного событийно-ориентированного программирования на php — в студию, пожалуйста.

Прекращайте вестись на hype. Даже в рамках веб-сокетов это банальные запрос-ответ или стейт-машины.

> А также было бы интересно услышать о том, как можно общаться между различными php-процессами (отправляющими и принимающими сообщения)

А зачем их разделять?
UFO just landed and posted this here
> Это даже критикой назвать нельзя — это троллинг.

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

> а еще его пиарят какие-то отморозки… Мамут вообще неадекватный — ничего спросить нельзя, набрасывается сразу

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

Более того, в последних двух топиках (один из которых этот) про Erlang я вообще не начинаю говорить. Что опять же характеризует не меня, а людей, неспособных понять те простейшие вещи, что я пишу.

На все вопросы я четко и конкретно отвечал. Хотя, если ваш друг — школьник типа тут: habrahabr.ru/post/160447/#comment_5505135 то мне жаль вашего друга (подробнее: habrahabr.ru/post/160447/#comment_5514995)

> Вы олицетворяете Erlang для масс, а ведете себя очень странно. Вам не плевать, чем пользуется конкретно этот товарищ?

Мне плевать. И вопрос я задал совершенно конкретный: Почему нагромождение технологий друг на друга называется «упростить процесс»?

Где вы здесь видите хоть слово про Erlang?

P.S. На остальные вопросы в этом топике, увы, отвечать не буду, потому что школота, неспособная понять простейший текст, успела снова слить мне карму.
P.S. На остальные вопросы в этом топике, увы, отвечать не буду, потому что школота, неспособная понять простейший текст, успела снова слить мне карму.

Грамотный вы наш дружище, прежде чем так откровенно сливаться, ответьте простейшим текстом хотя бы на этот простейший вопрос: как можно не разделять процессы в php, имея необходимость поддерживать постоянное соединение с клиентами по вебсокету и отвечать на традиционные http-запросы? И как можно без чего-то вроде redis общаться между ними, если процессы работают на разных машинах (мы же ведь грамотные и думаем про масштабирование)?

На вопрос, какого черта это всё надо писать на php, когда есть гораздо более удобные ЯП, ответа даже уже и не прошу.
UFO just landed and posted this here
Дмитрий, я не считаю, что нагромождение технологий — это упрощение.

Тут дело в том, что иногда задействование какой-то иной технологии, нежели использование той, к которой привыкли, может резко сократить количество необходимого кода для решения конкретной задачи. Собственно, технологии для этого и создаются. Примерно это я имел в виду в топике под «упрощением».
UFO just landed and posted this here
Подождите, вы тоже, что ли, будете утверждать, что без redis здесь можно обойтись? Вообще, если говорить о практике, то redis на сервере работал задолго до этой задачи для других целей. Но даже и без этого тут его определенно пришлось бы ввести. Это раз.

А вот два: демон на php является другой технологией, другим звеном по отношению к cgi на php. Он будет работать как совершенно отдельное звено, и неважно, какой именно интерпретатор запускается внутри /etc/init.d/websocket-server. При этом js как язык существенно удобнее php в данном круге задач.

Поэтому получаем: «node.js+redis+php-cgi» vs «php-daemon+redis+php-cgi». Где я неправ?
UFO just landed and posted this here
С тезисом про упрощение в данном случае теперь, надеюсь, согласны?

Технологический парк проекта при решении этой задачи было бы невозможно не усложнить — просто по той причине, что в «дано» задачи внесена новая технология, вебсокеты и постоянное подключение клиентов к серверу.

А кодирование упрощается выбором правильных инструментов для этого. И выбор этих инструментов осуществляется с нуля, так как задача тоже поставлена с нуля.
UFO just landed and posted this here
Вероятно, в данном случае «они» предлагают написать собственный pubsub-демон на сях, который будет висеть на TCP-порте и будет рассылать туда-сюда сообщения из php? А потом допишут к этому сервису текстовый протокол передачи для удобства и выложат в мир под названием… ну скажем, myRedis.

Это, знаете, похоже на такого анекдотичного программиста, до старости доводящего до совершенства код одной-единственной функции.
UFO just landed and posted this here
У меня на отдельном сервере работает ejabberd — чат для Клавогонок. На эрланге. Хорошая штука, я вдоволь в нем поковырялся.

Я знаю о богатых возможностях создания процессов в эрланге. Однако возможность расползаться по памяти нескольких машин мне неизвестна. Поэтому какая-то общая среда, всё же, нужна в любом случае. Даже если она есть своя собственная в эрланге, в php её нет.
Можно обойтись. Возможно Redis не лучший выбор для реализации обмена сообщениями, а, скажем, Gearman бы больше подошёл. Но вы решили на нагромождать технологии :)
Обойтись без чего-то вроде redis вообще, а не без конкретного redis в частности.
> Подождите, вы тоже, что ли, будете утверждать, что без redis здесь можно обойтись?

Можно ли обойтись без redis для pubsub? Вот скажите, почему ни одной из *MQ решений не подошло для pubsub между процессами? Начиная с ZMQ, которому даже отдельный демон не обязателен?

Я понимаю, что там есть pubsub, но redis — key/value в первую очередь. В заточенных на MQ решениях всё намного круче и гибче.
Не-не, вы не поняли контекст этого треда комментов. Конечно же имеется в виду не сам Redis как таковой, а отдельно стоящий pubsub-сервис. dmitriid предлагает обойтись вообще без оного. Не представляю, как.
UFO just landed and posted this here
тыц:
ВНЕЗАПНО оказалось, что надо еще каким-то образом общаться между node.js и PHP. Правильно, давайте навернем еще сверху pubsub через редис.

Так как от дальнейшей дискуссии товарищ ушел, то я интерпретирую его слова самостоятельно: если бы не было node.js, то и redis как pubsub-сервис бы не понадобился. Вопрос, какое отношение имеет выбор интерпретатора демона к необходимости завести общую среду передачи сообщений, остается невыясненным.
Если вернуться к гипотезе о том, что критика была про редис, а не про сам pubsub в качестве IPC. Редис, а не что-то другое, необходимость? Что ещё делает редис?
Критика была о том, что вообще нужен pubsub, так как-де «надо еще каким-то образом общаться» между двумя разными платформами. Как будто «каким-то образом общаться» не придется, если вторая платформа будет не на js, а на php.

Редис в данной задаче нужен только для pubsub, больше ни для чего. А в целом пригодится и как кэш, естественно.

Писать свой pubsub просьба не предлагать :)
Ну как же:
Итак. У вас уже есть сайт на РНР. Вам нужно решить какую-то задачу. Вы почему-то взять node.js (хотя работа с вебсокетами в PHP более, чем возможна). ВНЕЗАПНО оказалось, что надо еще каким-то образом общаться между node.js и PHP. Правильно, давайте навернем еще сверху pubsub через редис.

По-моему вполне недвусмысленное предложение избавиться от node.js и redis. Демона для веб-сокетов написать тоже на PHP и средствами PHP же реализовать обмен сообщениями между CGI-частью и демоном. Возможно? Возможно. Имеет ли смысл без самоцели избежать «нагромождения технологий»? Ни одного аргумента за это, просто голословное утверждение. Причём почему-то лояльность к nginx, а ведь асинхронный событийный веб-сервер тоже на PHP можно написать. И базу данных или другое хранилище. И никакого нагромождения технологий — ОС и один процесс PHP в памяти. Ну или несколько процессов/потоков если выбрать другую модель.
Вместо редиски вполне можно слать данные в сокет, а в ноде слушать его. Итого — минус редиска.
Плюс своя реализация сообщений в ноде (хотя может она там есть, но по контексту -нет)
Насчет pubsub без редиса — переносите очередь сообщений в NodeJS и всё.
Делаете в Node внутренний URL /post_message и из PHP обращаетесь туда HTTP клиентом с теми же данными, какие пихали в редис.
Чем такой подход не устраивает?
Вроде в редис обращаются из пхп-апи…
Нод может быть запущено много, и они могут быть на разных машинах. При этом разные клиенты подключаются к разным нодам через балансировщик, но получать должны одни и те же сообщения от бэкэнда.
Свой код зачастую оказывается самой ненадежной частью программного комплекса. Особенно если код низкоуровневый, системный, а ты в этой области обладаешь в лучшем случае лишь общими теоретическими знаниями. Ладно если стоит альтернатива свой код или код другого одиночки. Но вот что 100 строк своего кода более надежны чем даже миллион строк кода продукта с большой историей, крупным сообществом, финансируемого крупной компании далеко далеко не факт.

Так что 10 своих строк и качественный продукт на миллион строк, как минимум, аргумент, который нужно рассмотреть против 100 своих строк, даже с точки зрения надежности. А надежность не единственный фактор для выбора. В пользу 10 строк говорят ещё такие факторы как скорость разработки и простота поддержки.
UFO just landed and posted this here
Утверждение «10 строк не аргумент» как минимум спорно даже с точки зрения надежности. А надежность не единственный критерий выбора способа решения задачи.
Отвечу только один раз.

> > Hype Driven Development во всей красе
> Вот, например. Это я и считаю троллингом.

Давайте восстановим контекст:

"
> Это (php + redis + node.js?) совершенно минимальный джентльменский набор риалтаймового проекта.
Hype Driven Development во всей красе.
"

Это не троллинг, а называние вещей своими именами.

> Если бы вы были чуточку добрее к людям, вы привлекли бы на свою сторону гораздо большее количество людей. Потому, что мы — люди — не мухи. Нам не плевать, на что слетаться.

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

Хотя нет, пусть они будут на другой стороне.

PS.

В частности, в комментариях было объяснено, что автор топика планирует перейти с php на node.js полностью (что уберет кусок нагромождений). Если бы это было сказано сразу, я бы слова не сказал. Возможно, у меня были бы другие возражения, но вряд ли (обычно у меня возражения только по обилию слюней в описании крутости node.js)

А в топике общее описание идет в стиле «вот у нас есть куча разрозненного всего, мы это свяжем вместе костылями из говна и палок» с неожиданным выводом «это удобно и все упрощает!». Будет смешно, если там рядом еще где-то валяется MySQL/Postgres для данных, а редис прикручен только ради pubsub'а.
А в топике общее описание идет в стиле «вот у нас есть куча разрозненного всего, мы это свяжем вместе костылями из говна и палок» с неожиданным выводом «это удобно и все упрощает!».

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

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

И вы до сих пор не оказались способны доказать мне, что это можно решить более просто в технологическом плане.
UFO just landed and posted this here
Вы действительно считаете нагромождение технологий друг на друга упрощением?

Если они не дублируются и используются по назначению, то да. Как правило они предоставляют высокоуровневые интерфейсы к реализации нужных для проекта функций. Выбор состоит лишь в том, что использовать: специализированный инструмент, универсальный инструмент с какой-то обвязкой или полностью свою реализацию. Вот стоит задача обмена сообщениями между двумя процессами, пускай даже написанных на одном языке, но возможно исполняющихся на разных машинах. Можно взять Redis, в котором эта функция реализована «из коробки», имеет привязки ко множеству языков, имеет крупное сообщество, финансируется и курируется известной компанией, для которой наличие эффективного способа обмениваться сообщениями между процессами на разных хостах (пускай и виртуальных) большой плюс в их основном бизнесе. Можно взять MySQL и использовать его для хранения сообщений, написав обвязку для работы с ними. Можно написать полностью свое решение на любимом языке, используя только низкоуровневые средства ОС вроде сокетов или файлов. Какой способ будет проще? Какой способ будет проще? Тот, где абстракция сообщения уже реализована, тот, где реализована абстракция записи, вокруг которой можно реализовать абстракцию сообщения или тот, в котором реализована только абстракция потока байтов, а всё остальное нужно реализовывать самому?
Прекращайте вестись на hype. Даже в рамках веб-сокетов это банальные запрос-ответ или стейт-машины.
Я разве говорил про node.js? Я говорил просто про js. Вы, похоже, совсем не учитываете инструментарий языка при выборе решения задачи, а просто выбираете «что привычнее». Раз уже что-то написано на php, значит и дальше пишем на php, да? Но, я надеюсь, вам не надо объяснять всю колоссальную разницу между асинхронным программированием в php и js?

А зачем их разделять?
Затем, что эти процессы могут работать физически на разных машинах (что на Клавогонках они в данный момент и делают). Да и вообще, простите, как можно не разделять php-процессы в данном случае?
UFO just landed and posted this here
Ну я повторюсь, я нигде не говорю о node.js, я говорю о языке javascript. Был бы традиционный веб-сервер на js, а не событийно-ориентированный, я бы все равно использовал его. А товарищ предлагает вообще использовать php, что для данной цели довольно дико.

Здравое зерно в его рассуждениях я не уловил ни по одному пункту. Выпады против redis вообще мне кажутся следствием довольно поверхностного понимания темы.
UFO just landed and posted this here
Мне кажется, я понял эту мысль из его первого же коммента и сразу же предложил ему показать более минималистичный по количеству технологий способ решения данной задачи, что он до сих пор не сделал. Он предложил заменить одно звено другим — node.js на демон на php. При таком ходе количество технологий не уменьшается, потому что демон на php и традиционные cgi на php — это две большие разницы. Причем предложил делать это просто по историческим причинам, так как уже что-то работает на php, что я вообще не могу принять как показатель профессионализма.

Товарищ, возможно и не дурак, я вполне могу с этим согласиться, только в данном конкретном обсуждении он проявил либо интеллектуальную лень, либо желание завернуть тему в какую-то свою любимую сторону, не разобравшись в вопросе.
Разделять можно хотя бы для того, чтобы отделить сервис от данных.
В эрланге, как мне известно, можно подменять отдельные участки кода, там же где этого нет искаропки, приходится выполнять разделение на несколько сервисов.
Да и действительно, не очень php подходит для демонов, то, что какая-то морда сделана на php не значит, что на нем надо делать все.
phpdaemon и shm_*/msg_*, затрудняюсь сравнить их с node.js и redis по удобству и другим параметрам, только присматриваюсь к долгоживущим процессам, событийной модели и т. п., но они есть.
Они, разумеется, есть, это же php — самое большое программерское коммьюнити в мире! Но вот я лично вряд ли могу назвать их удобными.
Пробовали, рассматривали? Если да, то может напишите пост о впечатлениях?
Вскользь смотрел. Меня сам по себе язык для этих целей не устраивает. Реальный выбор был только между Twisted и node.js. После некоторого исследования вопроса (например), остановился на node.js.
UFO just landed and posted this here
Нет-нет. Именно язык. Вы знаете, замыкания там всякие, прототипное наследование, variable scope и т.п.

В 5.3-5.4 ситуация чуть получше, но до критической отметки не достает.
Кстати, если очень хотите event-driven фреймворк на php, то лучше трясите Котерова, чтобы запилил в свою либу вебсокеты, может выйти что-нибудь толковое.
libevent позволяет общаться между процессами php. Но без крайней необходимости лучше этого не делать (лучше вообще не трогать эту штуку), проблем хватает. node.js действительно удобнее, проще в использовании и дает большую производительность.
Как я понимаю, для работы с вебсокетами по любому нужно отказываться от CGI модели в паре с сервером типа nginx или apache и писать демона. Так ли уж важно на чём он будет написан, если обоими языками (PHP и JS) и необходимыми фреймворками владеешь на одинаковом уровне?

Если у нас отдельный демон и CGI-сайт на PHP, то по любому какую-то технологию межпроцессного взаимодействия использоваться придётся. Так ли велика разница какую именно, если пока ни одна в проекте не используется?

Не, можно, конечно, использовать, скажем, phpdaemon для написания демона, а mysql в качестве средства IPC (собственно у меня он сейчас так и используется кроме всего прочего), но есть ли смысл держаться одно стека технологий, если другие, допустим, справляются лучше?
Вот чем отличаются отечественные IT ресурсы от зарубежных вот уже несколько лет — наличием таких обосрательных постов. Это не признак «наличия собственного мнения», а признак «отсутствия культуры».
А вы пробовали на PHP работать с вебсокетами?
Я вот на phpdaemon 2 дня потратил, node.js оказался проще и надежнее в этом плане.
Можете рассказать об опыте? В идеале постом. Просто я и там, и там «хееловорды» писал по хаутушкам, большой разницы не заметил. Но все отличия JS от PHP изучал в процессе.
Я не настолько разобрался в phpdaemon, чтобы писать о нем))
Вышло только заставить принимать запросы вебсокет-клиентов и выдавать ответы. Чуть-чуть сложнее чем в примерах. Broadcast сообщение от сервера клиентам вообще магически срабатывал 1 раз из 4х.
Интерес на дальнейшие статьи, само собой, есть.
Скажите, а в сторону Dklab Realplexor не смотрели?
Там уже есть готовое API для php. Правда там реализация, на сколько я понимаю, только через long polling.

Ну и, на одной из конференций, ребята из геометрии немного ругались на Socket.IO (презентация)
Из слайда Sucked.IO
• Утечки памяти
• Необъяснимые падения
• Нестабильный Long polling
• Проблемы с Flash Socket
• Heartbeat’ы влияют на производительность и задерживают
доставку сообщений
• Хуевый дизайн приложения

и предложили свой велосипед — Beseda. А после доклада, один из присутствующих в зале, очень хвалил решение от Котерова.
Смотрел давно, но всерьез не рассматривал, так как тут нужно именно полнодуплексное соединение. То, что описано в этой статье — лишь первый этап, в дальнейшем я планирую и основной игровой движок перетащить на эти технологии, что даст сильно больше возможностей. А там много двустороннего обмена, который не сделать в рамках обычных HTTP-соединений как в либе от Котерова.

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

Проект у вас отличный, сейчас жена на нем играет-тренируется :)
Есть такая штука — SockJS. Идея проекта — дать разработчикам вебсокет-подобный объект на клиенте и он уже сам будет откатываться на поддерживаемые протоколы.

Работает сильно лучше Socket.IO, является хорошим переходным решением — когда все браузеры начнут поддерживать вебсокеты, от него можно отказаться сменой создаваемого класса.

А что до Socket.IO — он действительно очень плохой, его совершенно не поддерживают. Вот пример эпического бага, который открыт год: https://github.com/LearnBoost/socket.io/issues/438#issuecomment-10620702. Если кратко, то в клиенте есть race condition, который не могут вылечить уже год и клиент начинает DDOS'ить сервер.
Спасибо, посмотрю. Но статья не совсем о Socket.IO, всё же. Больше о вебсокетах как таковых.
Да, но если есть необходимость поддерживать старые браузеры: Socket.IO не самое лучшее решение. А идти с чистыми вебсокетами — еще хуже, IE8-9 еще популярен.

Так уж сложилось что я с ним (и SockJS) уже около двух лет вожусь и Socket.IO совершенно не радует.
Обязательно попробую.
Я вот посмотрел на SockJS nodejs server. Не пойму а он умеет цепляться на Express или стандартный HTTP?
Прошу прощения за оффтопик, но означает ли это, что сокет.ио нельзя использовать в продакшене? Или есть какие-то определенные условия?
Использовать или не использовать в продакшене это каждый решает для себя сам исходя из своей задачи, тестов и… чужих мнений. У меня Socket.IO прекрасно работает и тоже скоро будет 2 года. Да были утечки, но они проявляются при определенных условиях. Я их нашел и сделал pull-request. Socket.IO просто считается перегруженным фичами. Он умеет отдавать своего же клиента сам. Есть поддержка подтвержающих коллбеков (кстати источник тех самых утечек). Есть автоподнятие соединения при пропадании связи. С SockJS придется все это реализовывать самостоятельно. Да меньше фичей меньше багов — есть возможность наваять своих. Но свои ж они как-то роднее :-)
pull request не приняли?
Пока нет. Там на самом деле 3 реквеста. Два из них противоречат друг другу, описание приложено. Надо принять решение. Видимо облом вникать.
Ну реквестам не 2 года. Они связаны с коллбеками, которые я начал использовать недавно и заметил утечку. У вас коллбеков нет, как я вижу. А в самой Socket.IO все равно пришлось копаться потому что у меня клиент не стандартый. На MS ActiveScripting, ну по стути это движок от IE 8.0, только без браузера. Вместо браузера и DOM мои объекты. Так что я в него вкрутил WebSockets и делал там обертку, чтоб Socket.IO cliеnt думал, что он в браузере.
Коллбеки у меня в реальном коде, на самом деле, есть. Пойду медитировать над реквестами.
Лучше не использовать — сервера ложатся от нагрузки из за бага указанного по ссылке выше. Этот самый серьезный, по мелочи там хватает разного.

Сейчас все ждут Socket.IO поверх Engine.IO (Engine.IO это SockJS, но от разработчиков Socket.IO) или переходят на что-то более стабильное (Faye, SockJS, etc).

Что до SockJS… В плане функциональности — это вебсокеты и ничего больше. Нет событий, нет каналов из коробки (но есть отдельный мультиплексор — https://github.com/sockjs/websocket-multiplex), нет автоматического реконнекта, нет комнат и тому подобного.

И, если честно это хорошо. Очень сложно угадать что потребуется разработчикам: как группировать клиентов, как должен работать реконнект и т.д.
Ну мне важна поддержка редиса и все. Комнаты я сам контролирую. Вопрос в другом — при каких условиях проявляется описанный выше баг? Ведь если все так плохо, то почему еще все не начали использовать другое решение?
Почему не начали?

Крупные ресурсы, которые хоть какую-то имеют нагрузку переезжают на альтернативные варианты.

Для «поиграться» (всякие небольшие проектики, proof-of-concept, etc) вполне себе нормально работают на Socket.IO. Там не такие нагрузки, что бы спровоцировать этот race condition.
Не сочтите за наглость, можно пруфы того, что переезжают? Если так, то насколько сложно переехать и на что?
По ссылке выше есть немного (в тикете Socket.IO).

PythonAnywhere (облачная питоновская консоль) переехала. Одна из причин была стабильность Socket.IO, вторая — у SockJS latency меньше. blog.pythonanywhere.com/27/

Знаю несколько человек, которые долго долбили багтрекер Socket.IO (@dominiek, тоже есть в том тикете), перешли со своими проектами на SockJS.

Metor тот же (который на node.js) сначала был на socket.io, потом его выпилили и сделали SockJS.

Ну и так далее.

Переезд — смотря сколько функционала завязано на фичи самого socket.io. Если используются event'ы — прийдется их руками сделать (или найти либу, вроде кто-то делал).
Вброс, и могу ошибаться. Но разве веб-сокеты не были реализованы ~10 лет назад во флэше? Или там что-то другое?
Про флеш я в топике отдельно пояснил. Не дело это, для одного лишь транспорта использовать флеш, когда нигде больше он не нужен. Кроме того, я лично с флешем не дружу совсем. Кроме того, насколько я знаю, у флеша есть некоторые ограничения вроде необходимости открывать 843 порт, и следовательно, напороться на проблемы с прокси-серверами.
нет там ничего такого, и 843 порт не нужен — просто флеш при соединении к порту ниже 1024 ( а логично и проверено что для корректной работы и в корпоративной среде тоже, лучше использовать 443 порт), он запрашивает полиси файл. При этом запрос идет сначала на 843 как стандартный порт, а потом по тому же порту, что и соединения.
Была реализована другая технология полнодуплексного, афаик, обмена сообщениями между сервером и браузером. Но к стандарту веб-соектов она никакого отношения не имеет. Это две разные технологии с одним или схожим назначением. Технология, используемая во Флэше, частенько используется для эмуляции веб-сокетов, если браузер её не поддерживает. Собственно в статье она упоминается, 4% соединений идут через неё (а 90% через веб-сокеты).
кстати, говоря, флешевый сокет даже гораздо удобнее — там нет никаких ограничений и протоколов, просто обычный сокет.
Более гибкое скорее в следствии низкоуровневости. Как сравнивать Си и какой-нибудь высокоуровневый язык — кто из них удобнее?

Если мы посредством костыля флэша вводим в JS возможность работать с сокетами, то многое придётся придумывать и реализовывать самим и далеко не факт, что это получится лучше чем получилось у дядей из W3C и производителей браузеров.
ну, превоначальные протоколы ws были еще норм, а потом все усложнилось да так, что без либы сторонней и не реализуешь нормально. И хендшейк странный и фрейминг — очень часто, если не надо особых наворотов, на сокетах обычных куда проще. Хотя я не умаляю ws — это хорошо и отлично. Лишь бы кто выпустил вменяемую библиотеку для встраивания в существующий проект, а не мощные навернутые системы
Кстати, ещё такой вопрос.
Через сокеты вы клиенту отправляете сообщения с сервера.
А как происходит отправка сообщений от клиента на сервер? Через ajax?
Не знаю как автора, но вебсокеты двухсторонние можно и на сервер через них слать.
почему не поднять веб-сокет сервер на РНР?
Кстати, а можно пример такого сервера?

В целом, у автора сервер на node.js, общение между php и node.js происходит через redis
При отправке данных от php — вопросов нет. Это и описано в статье. А вот как эти данные получить (если они отправлены через сокет), непонятно.
Нет, у автора все отлично и правильно — через редис это самый хороший вариант, который и я использую и всем рекомендую ) тем более что редис можно еще много как использовать.

Пример? да запросто:

socketo.me
github.com/kakserpom/phpdaemon (сайт у них что-то тормозит, но автор есть и на хабре — habrahabr.ru/post/79377/) и там есть из коробки вебсокеты.
Я не говорю, что у него плохо :)
По ряду причин я выбрал для этого node.js — событийно-ориентированная модель и хорошо развитые коллбэки в javascript идеально подошли для этой задачи.
Общей средой общения между php-бэкэндом и сервером на node.js стали pubsub-каналы redis.


Я просто не в курсе, при отправке сообщения от клиента мы сможем это сообщение переслать в php скрипт?

client -> node.js -> redis -> ??? -> php

Кстати, спасибо за ссылки!
а, простите, не до конца понял вопрос.

Есть несколько костыльных вариантов, как я вижу:

— напрямую вызов РНР (по сути, через exec — это если код, обрабатывающий данные, обязательно РНР)
— посредством локального HTTP интерфейса (по сути, нода выступает почти прокси — приняла -> немного обработала -> если надо, сделала вызов localhost/script.php — зато такой вариант несколько быстрее и гибкий
— модификация первого метода, использую тот же FastCGI для общения с РНР.
Либо тупо отправлять через ajax от клиента напрямую в php.
Опять же, если через ajax, то ответ идет через сокет?
client -> ajax -> php -> redis -> node.js -> client
или сам php отвечает?
client -> ajax -> php -> client

Вот я и хотел уточнить, как это реализовано у автора.
У меня реализовано именно так, как пишет aleks_raiden — POST-запрос из node.js на локальный порт веб-сервера. Постепенно я буду от этого уходить, переписывая куски логики в самом node.js.
А реакция какая ожидается от PHP при получении клиентских данных по веб-сокету? Должен ли быть ответ клиенту, сформированный PHP? Должна ли быть реакция PHP мгновенной?

Если рассматривать простейший случай (ответ не требуется или достаточно лишь статуса, что данные успешно переданы в php, обработка не должна быть мгновенной и т. п.), то демон, обслуживающий сокеты просто пишет куда-то (файл, разделяемая память, субд, сервер сообщений, сервер очередей и т. п.) данные для php, рапортует если нужно о статусе, а уж php обрабытывает эти данные когда «захочет» (по запросу пользователя, по запросу скрипта в браузере, по крону и т. п.).
Сценарий:
Во время гонки была нажата клавиша «а»

Естественно надо это дело обработать и, как можно скорее, сообщить другим участникам гонки, что машина продвинулась.

В простейшем случае, я бы данные от клиента отправлял напрямую в php скрипт (ajax), а другим участникам рассказывал бы через сокет. Но, в случае с клавогонками можно заддосить сервер, ибо каждую нажатую клавишу надо отправить на сервер и таких клавиш много (от всех игроков онлайн).
Вот чтобы не ддосить сервер, надо отправлять не через ajax, а по сокету, там оверхед поменьше. А node.js передаст, кому надо. Может, даже сразу в базу что-то запишет, а php по завершению заберет агрегированные данные. Ну или POST на скрипт.

Хотя на каждую клавишу слать событие — это, конечно, жестоко.
Я бы вообще задумался о необходимости PHP (или другого CGI/CLI-скрипта) в данном сценарии. Вернее о необходимости полной синхронной обработки. Получили через веб-сокет сообщение от клиентском событии, просчитали необходимые здесь и сейчас для отправки результаты (позицию машинки или даже дельту её смещения, если явного финиша нет), вытащили из памяти список тех, кому надо его отправить (явно или имя общего канала), отправили, сделали, если необходимо, запись в базу или положили сообщение в очередь для более поздней синхронной обработки (по запросу пользователями или таймеру) и спим до следующего события. Причём спать ложимся как только дали команду на рассылку и запись в базу или очередь. А вот когда заезд завершен, можно обычным php скриптом посчитать статистику, определить победителя, дать ему награду и т. п. обработав все записи о клиентских событиях за один проход.
вебсокеты являются двунаправленным каналом.
Думаю для одного небольшого проекта попробовать вот такую штуку:
github.com/wandenberg/nginx-push-stream-module

Бонусы:
— вся мощь nginx в обработке асинхронных запросов
— поддерживает несколько способов раздачи одновременно — polling, long-polling, eventsource, websockets
— в комплекте есть js-библиотека, реализующая их все и умеющая graceful degradation, но можно и самому все сделать.
— можно использовать как простенький сервер очередей
— включен в пакет nginx на dotdeb, то есть ставится без свистоплясок одной командой или уже есть

Идея в том, чтобы всю раздачу сообщений пользователям свалить на полностью готовое решение, а существующий бэкэнд сделать максимально тупым, чтобы он только постил апдейты в канал.
Отпадает необходимость городить отдельный сервер на node.js+redis и подобном.

Обратный канал оставить на классическом xhr+fastcgi, он все равно нужен, если делать graceful degradation.

Теоретически модуль умеет принимать publish в канал с клиентов, подключившихся через вебсокеты, но реализовано это как-то коряво (publish делается в тот же канал, на который была подписка).
Если очень надо, можно, наверное, открыть второе websocket-соединение на отдельный канал чисто на отправку, хоть это и костыль.
Тогда можно и fastcgi выкинуть совсем, читать сервером сообщения, прицепившись локально к nginx через обычный http streaming к этому каналу.
Ну, если вы действительно хотите писать реагирование на входящие от клиентов события на php, то почему бы и нет. Как по мне, так js для этого подходит куда лучше.
Я разве где-то упомянул php?
Можно, на самом деле, и обычный xhr post засовывать в ту же очередь вместо fastcgi, и затем чем прицепились к очереди, тем и читаем, хоть bash-скриптом.
Хотя, по-моему, чтобы не плодить сущности, удобнее это делать на том же языке, на котором написана остальная логика.
Раз уж не надо самому возиться с многопоточностью (эта работа взвалена на откомпилированный сишный модуль), почему бы и нет.
Если воркер все же нужен многопоточный, то непонятно, чем плох fastcgi, который все равно уже есть.
Возможно, для какого-то узкого круга задач это будет более эффективно, да. У меня же тут планы завязаны на перенос большой части логики в node.js, оттого так.
Интересно, но как-то кажется, что архитектуру это не упростит, если добавить, например, аутенфикацию и авторизацию.
Да, решение больше ориентировано на broadcast одного канала всем желающим, чтобы application-серверу было вообще пофигу, сколько их там висит.

Персональные каналы я бы делал так:
— id канала — это хэш наподобие session id, можно даже его и использовать, модуль умеет читать id канала из кук
— каждый клиент подписывается одновременно на два канала — общий и свой персональный, модуль это опять же умеет делать в рамках одного соединения.
— если сессия стала невалидна — убиваем канал с сервера

Безопасность получается на том же уровне, что и остального приложения (угон id канала равносилен угону сессии), если надо — завернули все в https средствами того же nginx.
А зачем вам flashsocket & jsonppolling?

и Opera (кроме мобильных) и IE (за 6-й, вот точно не скажу) — прекрасно живут с xhr-polling.

У нас стабильно xhr-polling + websockets
Почему xhr-polling плох в моем случае, я описал в самой статье. Очень частые запросы и оверхед.
Понятно. Мы решили уменьшить количество сущностей.
Всё равно сокетная часть размазана по кластеру и там уже не так страшно 40к одновременных будет, или 70к…
А вы — это кто, если не секрет? Интересно посмотреть на кухню.
Надеюсь что к понедельнику допишу статью и поделюсь ссылкой.
Увы по основному high load — жёсткий NDA.
Кухня — erlang ;-)
А какая у вас нагрузка на Socket.IO выходит? И на каком сервере все крутится?
А то поначалу оно обычно всегда нравится и удобно, а потом оказывается, что течет и имеет фатальные проблемы с производительностью при серьезных нагрузках.
Socket.IO используется в больших проектах. Даже если с ним будут проблемы, от него можно не сильно болезненно отказаться, а голый node.js используется не в больших, а в очень больших проектах и замечательно масштабируется.

Сейчас вебсокетовый сервер работает на Intel Core2Quad Q8300 2.5GHz, занимает около 120 мб памяти и не более 8% цпу при нагрузке, которую вы примерно можете оценить сами на сайте.
Насчет замечательной масштабируемости можно поспорить. Все-таки V8 однопоточный по природе своей. И родной нодовый cluster имеет забавные побочные эффекты из-за этого.
А Socket.IO имеет их еще больше, потому что изначально был расчитан на одно ядро, а потом туда воткнули redis, который местами забыли прикрутить, отчего то теряются сокеты, то наоборот плодятся не в том потоке, где надо.

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

А нагрузку на сайте оценить к сожалению не получится. Как показала практика, socket.io довольно легко держит и тысячу одновременных соединений, если они уже установлены. Самой дорогой операцией оказался коннект/дисконнект. Вот и интересно, сколько их у вас в единицу времени? Если считали, конечно.
Так и пусть однопоточный. Что при отсутствии разделяемых глобальных данных мешает запускать любое количество нод позади балансировщика?

Самой дорогой операцией оказался коннект/дисконнект. Вот и интересно, сколько их у вас в единицу времени? Если считали, конечно.

Немного. Примерно 30 в минуту. Но я сомневаюсь, что на это уходит большая часть производительности, потому что сообщения льются в канал непрерывным потоком, это грузит сильнее.
Любое количество нод запустить не проблема. Но проблемой становится синхронизация их между собой. Особенно, если речь идет, например, о пользователях, которые должны между собой общаться, независимо от того, к какому экземпляру ноды они прицепились при коннекте.

Непрерывный поток будет даже без сообщений. Потому что каждому клиенту Socket.IO посылает heartbeat и ожидает отклика. Ну при 30 коннектах в минуту в принципе еще все хорошо должно быть.
Ну а синхронизация решается опять же различными технологиями разделяемой памяти или этот же pubsub. Решать эту задачу на внутрипроцессном уровне в node.js противопоказано в принципе.

Непрерывный поток будет даже без сообщений. Потому что каждому клиенту Socket.IO посылает heartbeat и ожидает отклика. Ну при 30 коннектах в минуту в принципе еще все хорошо должно быть.

Я имею в виду, нагрузку на саму ноду, а не на Socket.IO (видимую в top).
Да, сейчас нагрузка пока никакая в общем-то. Будем смотреть внимательнее, когда на вебсокеты переедут другие части движка.
Спасибо за интересный пример использования вебсокетов.
Интерес к дальнейшим статьям есть, особенно к AngularJS.
Уже есть статьи по этой теме, но и вообще от себя скажу что штука хорошая стоит использовать, опять же кантора серьезная :)

Хотя новые статьи будут не лишними.
Интересно будет почитать про Angular.js, особено если есть возможность сравнить в статье с Knockout.js — плюсы, минусы, юзкейсы того и другого.
Присоединяюсь, все познается в сравнении :-)
По моим ощущениям основная разница — knockout.js для отслеживания изменений в модели дата-биндинга использует сложную систему коллбэков (observables) и отслеживания зависимостей данных друг от друга; а angular.js делает простую проверку на измененность данных (dirty check) каждый цикл по всем данным в модели вообще. И как по мне, так второй способ гораздо лучше в большинстве случаев.
Во многих проектах для реалтайма использую dklab.ru/lib/dklab_realplexor/ Помоему это намного проще чем вебсокеты которые работают только в хроме.
Из статьи же видно, что при доле Хрома в 51%, используют вебсокеты 90% клиентов, то есть ещё 39% браузеров, что больше доли фокса и оперы вместе взятых.
Вебсокеты работают в:

Firefox 6+
Chrome 4+
Safari 6+
Opera 12.10+
IE10+

Realplexor использует xhr-polling, что применимо далеко не во всех случаях. Например, непрерывный стриминг сообщений с клиента на сервер на нем в принципе сделать нельзя.
Comet уже не тот. Зря чтоли трудились над стандартами веб-сокетов и HTML5 SSE.
UFO just landed and posted this here
UFO just landed and posted this here
А в чем, собственно, проблема-то? Мне кажется, уж логирование — это последнее, что должно вызывать трудности.
UFO just landed and posted this here
Все равно не понял. Логирование подключенных клиентов? IP-адреса?
Как-то навернул в своем дипломном проекте систему с брокером AMQP в качестве промежуточного звена (эдакий pub/sub). Необходимо было в реалтайме оповещять клиентов о новой информации, которую скрапит веб-паук. Даже заработало.

image

После того, как я все написал, стало понятно, что архитектура не самая оптимальная.
Вот это я понимаю, нагромождение технологий. :)
Если отбросить клиентскую часть, то: AMQ server, база postgresSQL, (веб?) сервер на питоне, паук на питоне и memcached. В отличие от топика: 1 сервверный язык, а не 2; добавился memcached; не видно апача/nginx-а.

По мне не сложнее чем в топике, просто картинка страшнее из-за деталей вроде «разграничения прав» или названий библиотек.
Sign up to leave a comment.

Articles