Создаю чат. WebSocket.

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Создаю чат. WebSocket.

Сообщение girmate »

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

В чат могут оставлять сообщения авторизованные пользователи, остальные могут только читать. Это задача RBAC и ACF, поэтому эту часть пока не беру во внимание.

Создаем модель:
- количество записей предусматриваем много, поэтому primary_key (id) пусть будет bigint
- конечно же нам нужно знать кто прислал сообщение, добавляем поле user_id (int), где будем хранить id автора сообщения
- собственно, само сообщение text (с типом text)
- дата создания сообщения created_at (int)

Итак, получилась модель
id, user_id, text, created_at
Но, подумав, я решил что пусть в этом чате пользователи могут оставлять личные сообщения. То есть кликают по имени юзера и тогда сообщение видит только тот пользователь, кому оно адресовано.
Добавим в модельку поле for_user(int), где будем хранить id пользователя для кого предназначено сообщение.
Теперь наша модель (пусть это будет Chat) выглядит следующим образом:
id, user_id, for_user, text, created_at
Возможность отправки в общий чат картинок, файлов и прочей лабуды пока исключаем. Чат нам нужен просто для общения "текстом".
Как же мы будем выбирать сообщения. Я думаю что проблем особых нет

Выбрать все записи, где for_user равен равен NULL, либо for_user равен id пользователя просматривающего чат (исключаем чужие сообщения), сортируем по id в обратном порядке, ну и лимит 50 какой-нибудь. Так мы получаем все сообщения которые отправлены в общий чат или лично нам, выбираем последние 50 записей с конца. Конечно же через with подгрузим id-шники пользователей из связанных таблиц

Вроде бы все так пока что?

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

Добавим в таблицу USER поле mute (int), где будем хранить время окончания мута (например, текущее время + 3600 [1 час] ), и каждый раз проверять его когда пользователь хочет что-то в чат написать. Если в поле стоит время то проверяем, истекло оно или нет и:
- если истекло, то обнуляем это поле в NULL и разрешаем пользователю отправить сообщение
- если не истекло, то пользователь пока не может еще писать в чат
- если поле =NULL - сообщение можно принять и положить в БД (Chat)

Скажите, есть ли у вас замечания по моему ходу мыслей? Буду рад любым комментариям.
Последний раз редактировалось girmate 2016.11.02, 18:15, всего редактировалось 3 раза.
Осторожно! Вы общаетесь с новичком ;)

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

Виджет планирую обернуть Pjax. Виджет будет делать запросы на сервер каждые 3 секунды (ну или около того). Но не совсем понятно как лучше отдавать сообщения.

Вариант 1. Запрашивать все новые сообщения с id большим последнему полученному сообщению, но не старше 1 часа. Таким образом исключаем запрос когда в ответе будут содержатся все 555 сообщений, если вдруг у кого-то "старый" id=1.
Вариант 2. Выбирать все сообщения за последнюю минуту, и отдавать их клиенту, а уже на стороне клиента отсекать те сообщения, которые у него уже имеются. Но тогда много лишних сообщений в выборке, что больше нагрузит сервер.
Осторожно! Вы общаетесь с новичком ;)

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение zelenin »

почему не вебсокеты?

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

zelenin писал(а):почему не вебсокеты?
Я даже не знаю что это такое, какой профит от этого и насколько это сложнее. [пошел читать]. Нужно на сервере какое-то программное обеспечение дополнительно устанавливать? У меня будет обычный shared-хостинг.
Осторожно! Вы общаетесь с новичком ;)

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

Немного прочитал про сокеты, пока что понял что это лучшее решение, когда идет частый обмен данных (для чата самое то), а также для систем мониторинга в реальном времени. Но если нужен какой-нибудь node.js, то наверное не получится развернуть на моем хостинге такое? Как это сделать малой кровью?
Последний раз редактировалось girmate 2016.11.01, 14:02, всего редактировалось 1 раз.
Осторожно! Вы общаетесь с новичком ;)

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение zelenin »

girmate писал(а):Немного прочитал про сокеты, пока что понял что это лучшее решение, когда идет частый обмен данных (для чата самое то), а также для систем мониторинга в реальном времени. Но если нужен какой-нибудь node.js, то наверное не получится развернуть на моем хостинге такое?
google => php websocket chat

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

zelenin писал(а):
girmate писал(а):Немного прочитал про сокеты, пока что понял что это лучшее решение, когда идет частый обмен данных (для чата самое то), а также для систем мониторинга в реальном времени. Но если нужен какой-нибудь node.js, то наверное не получится развернуть на моем хостинге такое?
google => php websocket chat
Уже читаю.
Осторожно! Вы общаетесь с новичком ;)

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

to zelenin. Немного почитал. Есть вопросы. Я смогу запретить пользователю писать в чат? Я смогу помечать сообщения для некоторых пользователей (личные сообщения, которые видит только тот кому они предназначены)? Где хранятся все сообщения? Я смогу посмотреть историю сообщений за прошлый месяц?

P.S. Понятно, что все это можно. Вопрос сколько времени уйдет на изучение). Но штука крутая и я даже не подозревал что такое есть. Точнее название где-то слышал, но не думал что нужно мне.
Осторожно! Вы общаетесь с новичком ;)

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение zelenin »

веб-сокет - просто протокол обмена данными клиента и сервера.

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

zelenin писал(а):веб-сокет - просто протокол обмена данными клиента и сервера.
Александр, очень благодарен за наводку. Еще только начал изучать. Клиентскую часть посмотрел. Небольшой вопрос: почему так быстро происходит обмен? Что такого лишнего в обычном http, что он отдает данные не так быстро по сравнению с websocket протоколом? Причина в том, что websocket соединение может быть постоянно открыто?
Последний раз редактировалось girmate 2016.11.01, 16:20, всего редактировалось 1 раз.
Осторожно! Вы общаетесь с новичком ;)

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение zelenin »

girmate писал(а):
zelenin писал(а):веб-сокет - просто протокол обмена данными клиента и сервера.
Александр, очень благодарен за наводку. Еще только начал изучать. Клиентскую часть посмотрел. Небольшой вопрос: почему так быстро происходит обмен? Что такого лишнего в обычном http, что он отдает данные не так быстро по сравнению с websocket протоколом?
это постоянное соединение. а в обычном http (1.1) открываем соединение, передаем данные, закрываем соединение. Что а) медленнее для клиента б) тяжелее для сервера.

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

Да, я дополнил свой вопрос, мои предположения совпали с Вашим ответом. Отлично.
Осторожно! Вы общаетесь с новичком ;)

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

Самое интересное, я раньше ничего не знал про сокеты и часто думал каким образом на сайтах, где есть чат и туда пишут десятки пользователей одновременно - в окне чата обновление происходит почти мгновенно, ведь через ajax нужно время или таймаут. Теперь эта загадка разрешилась благодаря Вам.
Осторожно! Вы общаетесь с новичком ;)

sda
Сообщения: 334
Зарегистрирован: 2013.12.19, 09:29

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение sda »

girmate писал(а):Самое интересное, я раньше ничего не знал про сокеты и часто думал каким образом на сайтах, где есть чат и туда пишут десятки пользователей одновременно - в окне чата обновление происходит почти мгновенно, ведь через ajax нужно время или таймаут. Теперь эта загадка разрешилась благодаря Вам.
Неа, websocket это относительно новый протокол, приобрел статус RFC только в декабре 2011. Пока еще далеко не все его используют. Просто еще есть Comet это набор различных решений, которые позволяют отправлять данные (push) клиенту через HTTP протокол в режиме реального времени. Например long-polling в фейсбуке или http streaming в vk и telegram.

У long-polling суть в том, что клиент отправляет запрос на сервер и он там висит в цикле и ждет пока не появятся новые данные, как только данные появились они отправляются клиенту и соединение закрывается. Клиент получив данные сразу же открывает новое соединение. Если данные в течение определенного времени (например 20 секунд) не появились, то сервер закрывает соединение по таймауту и клиент сразу же открывает новое соединение.

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

У http streaming суть в том, что клиент отправляет запрос на сервер и он там висит в цикле и ждет пока не появятся новые данные, как только данные появились они отправляются клиенту, но в отличии от long-polling соединение не закрывается и сервер дальше продолжает ждать новые данные и отправлять их клиенту снова и снова. Затем сервер по таймауту (например 20 секунд) закрывает соединение, а клиент в свою очередь открывает новое соединение. В php можно реализовать через сброс системного буфера вывода с помощью функции flush.

Плюсы: те же, что и у long-polling плюс избавляемся от оверхедов на постоянные запросы когда новые данные сыпятся каждую секунду или чаще.
Минусы: web-сервер может буфферизировать данные перед отправкой клиенту, что не приводит к немедленной передачи данных в браузер, поэтому нужно уделить этому внимание и настроить веб-сервер соответствующим образом. Также некоторые версии Internet Explorer отображают данные только после получения 256 байт вывода, поэтому нужно раздувать отправленный пакет данных до этого размера например с помощью пустых пробелов. Но Internet Explorer уже RIP и поэтому на него можно забить, тем более, что эти версии точно также не будут работать и с websocket.

Кроме того есть еще ряд технологий например таких как SSE или внедрение невидимого flash размером 1x1 на страницу через который и организуется прием всех обновлений с сервера.

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

Аватара пользователя
vitalik1183
Сообщения: 1673
Зарегистрирован: 2014.07.01, 08:42

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение vitalik1183 »

вебсокет в итоге является самым перспективным решением на сегодняшний день?
Yii2!

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей.

Сообщение girmate »

Вчера 12 часов читал документацию. Технология зародилась в черновом варианте с 2009 года (или около того). Поддерживается всеми современными версиями браузеров. И оптимально использовать там где нужна мгновенная и частая двусторонняя передача информации - чат, игры, системы мониторинга и так далее. Я, благодаря Александру, узнал об этой технологии только вчера (ну отстал я, да). Скоро подготовлю несколько ключевых вопросов, попрошу чтобы немного рассказал. Как оказалась, клиентская часть очень проста, все самое сложное - на серверной стороне. Но в своем проекте я уже принял решение работать не только с чатом по протоколу websocket, но и еще в одном месте пригодиться. Решил разработку приостановить до получения более-менее вменяемых знаний, чтобы использовать это в своих проектах.
Осторожно! Вы общаетесь с новичком ;)

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей. WebSocket.

Сообщение girmate »

to zelenin и всем, кто уже сталкивался с websocket протоколом. Технология великолепная, конечно. После краткого ознакомления появились вопросы общего плана.

1. Как мне на серверном скрипте получить правильный id пользователя. Данным пользователя доверять нельзя. Значит нужен какой-то token или что-то вроде этого?

2. Как мне отправлять сообщения конкретному пользователю (личное сообщение в чат)? Искать его соединение (если я правильно понял) и транслировать туда?

3. Я так понимаю скрипт нужно запускать из консоли. То есть всю работу серверного скрипта я закину в консольный контроллер и запускаю. Так? Насколько я понимаю в консоли нет куков и сессий(или сессии есть?)

Ну вот хотя бы словами опишите что знаете. У меня еще не все сложилось, продолжаю штудировать.
Осторожно! Вы общаетесь с новичком ;)

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Создаю чат. Выкладываю свой ход мыслей. WebSocket.

Сообщение zelenin »

girmate писал(а):1. Как мне на серверном скрипте получить правильный id пользователя. Данным пользователя доверять нельзя. Значит нужен какой-то token или что-то вроде этого?

2. Как мне отправлять сообщения конкретному пользователю (личное сообщение в чат)? Искать его соединение (если я правильно понял) и транслировать туда?
google => php websocket chat
girmate писал(а):3. Я так понимаю скрипт нужно запускать из консоли. То есть всю работу серверного скрипта я закину в консольный контроллер и запускаю. Так? Насколько я понимаю в консоли нет куков и сессий(или сессии есть?)
а зачем вам куки и сессия?

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей. WebSocket.

Сообщение girmate »

zelenin писал(а):
girmate писал(а):1. Как мне на серверном скрипте получить правильный id пользователя. Данным пользователя доверять нельзя. Значит нужен какой-то token или что-то вроде этого?

2. Как мне отправлять сообщения конкретному пользователю (личное сообщение в чат)? Искать его соединение (если я правильно понял) и транслировать туда?
google => php websocket chat
girmate писал(а):3. Я так понимаю скрипт нужно запускать из консоли. То есть всю работу серверного скрипта я закину в консольный контроллер и запускаю. Так? Насколько я понимаю в консоли нет куков и сессий(или сессии есть?)
а зачем вам куки и сессия?
Да ну Александр! Я вчера 12 часов смотрел. И сегодня еще буду до глубокой ночи смотреть. Но очень мало информации на русском, на английском много непонятно. Но самое ужасное в этой теме, что 90% информации и примеров с уже готовыми расширениями. А мне не нужно расширение. Я хочу от простого - к сложному.

Я уже работал со скриптами-примерами, все получается (типа эхо-сервер). В общем случае - когда всем отдавать одно и тоже - вроде все понятно. Но же не буду личное сообщение От Васи к Пете транслировать всем.
Да еще и непонятно как узнать: где Петя, а где Вася. Мне не нужен код. Словами опишите план действий. Там еще есть ключи, которые генерирует браузер, может это как-то использовать.
Осторожно! Вы общаетесь с новичком ;)

Аватара пользователя
girmate
Сообщения: 1533
Зарегистрирован: 2015.10.27, 12:52

Re: Создаю чат. Выкладываю свой ход мыслей. WebSocket.

Сообщение girmate »

Видео на yuotube мне "очень" нравится (от Специалиста, например). Смотрим 1-й урок - все замечательно, понятно. Включаю второй - бац,- "а давайте скачаем расширение для серверной части". Накуя мне твое расширение, спрашивается??? И так во всех роликак Там Ratcher, а там на базе Node.js и там еще на чем-то. Чуть накопал на голом PHP.
Осторожно! Вы общаетесь с новичком ;)

Ответить