websocket notification
- vitaxa_prog
- Сообщения: 306
- Зарегистрирован: 2011.06.06, 22:44
- Откуда: Волноваха
websocket notification
Доброго времени суток, коллеги.
Занялся переводом системы уведомлений на веб-сокеты. Нашел в сети кучу примеров как реализовать чат. Но это немного не то что нужно.
В связи с этим возникло несколько вопросов из-за недопонимания технологии. Я понимаю как работает чат. Клиент отправил сообщение, сервер ответил всем клиентам. Клиент слушает сервер, сервер слушает клиентов. Тут все понятно.
А вот как реализовать это в системе уведомлений не пойму.
Например клиент подключился по websocket к серверу. Допустим сервер опросил базу данных на предмет не прочитанных уведомлений и ответил.
И тут возникает вопрос: Если в базе данных в дальнейшем, появились новые уведомления, как отследить их?
1. Опрашивать с клиента через какие то промежутки времени, сервер(setInterval)? Тогда чем это отличается от ajax?
2. На сервере через какие то промежутки времени опрашивать базу данных и при появлении новых записей, оповещать об этом клиент? Тогда нужно делать бесконечный цикл и sleep?
3. Не использовать MySQL? А использовать что то другое?
4. ...?
Посоветуйте знающие люди как лучше организовать такую систему?
Занялся переводом системы уведомлений на веб-сокеты. Нашел в сети кучу примеров как реализовать чат. Но это немного не то что нужно.
В связи с этим возникло несколько вопросов из-за недопонимания технологии. Я понимаю как работает чат. Клиент отправил сообщение, сервер ответил всем клиентам. Клиент слушает сервер, сервер слушает клиентов. Тут все понятно.
А вот как реализовать это в системе уведомлений не пойму.
Например клиент подключился по websocket к серверу. Допустим сервер опросил базу данных на предмет не прочитанных уведомлений и ответил.
И тут возникает вопрос: Если в базе данных в дальнейшем, появились новые уведомления, как отследить их?
1. Опрашивать с клиента через какие то промежутки времени, сервер(setInterval)? Тогда чем это отличается от ajax?
2. На сервере через какие то промежутки времени опрашивать базу данных и при появлении новых записей, оповещать об этом клиент? Тогда нужно делать бесконечный цикл и sleep?
3. Не использовать MySQL? А использовать что то другое?
4. ...?
Посоветуйте знающие люди как лучше организовать такую систему?
В принципе ничего нет невозможного.
— Вы думаете?
— Для человека. С интеллектом.
— Вы думаете?
— Для человека. С интеллектом.
Re: websocket notification
Ну если у вас все общение через вебсокет, то никаких проблем нет. При наступлении события вы просто рассылаете сообщение нужным пользователям.
Если событие наступает в результате например синхронного запроса, кто-то сохранил какую-то форму или из очереди чтото прилетело, то надо как-то пропихнуть это событие в демон вебсокета и сделать это быстро. Может быть при наступлении события класть что-то в кеш, а демон будет действительно в бесконечном цикле смотреть этот кеш. Как только видит что есть обновление он рассылает его нужным пользователям.
По пунктам:
1. Так действительно смысла нет, кроме того, что не надо каждый раз поднимать соединение.
2. Ну вот да, если у вас не все на вебсокете. Но лучше опрашивать не базу, а что-то побыстрее.
3. Тут смысл в доставлении события до демона, а не в средстве хранения данных.
4. В принципе ничего нет невозможного.
PS. Я с такой проблемой не сталкивался, просто я использовал вебсокеты. Так что все выше мои умозаключения.
Если событие наступает в результате например синхронного запроса, кто-то сохранил какую-то форму или из очереди чтото прилетело, то надо как-то пропихнуть это событие в демон вебсокета и сделать это быстро. Может быть при наступлении события класть что-то в кеш, а демон будет действительно в бесконечном цикле смотреть этот кеш. Как только видит что есть обновление он рассылает его нужным пользователям.
По пунктам:
1. Так действительно смысла нет, кроме того, что не надо каждый раз поднимать соединение.
2. Ну вот да, если у вас не все на вебсокете. Но лучше опрашивать не базу, а что-то побыстрее.
3. Тут смысл в доставлении события до демона, а не в средстве хранения данных.
4. В принципе ничего нет невозможного.
PS. Я с такой проблемой не сталкивался, просто я использовал вебсокеты. Так что все выше мои умозаключения.
2b||!2b Just read the instructions
- vitaxa_prog
- Сообщения: 306
- Зарегистрирован: 2011.06.06, 22:44
- Откуда: Волноваха
Re: websocket notification
Хм, спасибо. А это мысль. Может быть еще посмотреть в сторону чего то типа redis? Я конечно не силен в этом, но научиться никогда не поздно и никому не рано.
В принципе ничего нет невозможного.
— Вы думаете?
— Для человека. С интеллектом.
— Вы думаете?
— Для человека. С интеллектом.
Re: websocket notification
Конечно! Redis вообще шикарная вещь! Там можно тегировать записи и по тегам их получать. Еще если под докером работаете, то установка вообще будет очень простой. А доступ к редису из yii осуществляется через стандартный компонент. Так что ничего сложного в там нет.vitaxa_prog писал(а): ↑2017.09.11, 18:15 Хм, спасибо. А это мысль. Может быть еще посмотреть в сторону чего то типа redis? Я конечно не силен в этом, но научиться никогда не поздно и никому не рано.
Главное продумать хороший и надежный механизм передачи событий откуда угодно в демон через редис. Чтоб можно было отправить сообщение всем клиентам или одному конкретному.
2b||!2b Just read the instructions
- vitaxa_prog
- Сообщения: 306
- Зарегистрирован: 2011.06.06, 22:44
- Откуда: Волноваха
Re: websocket notification
Возникла такая мысль. А можно как то сигнализировать демону WebSocketServer, например из контроллера, что произошло какое то событие? Например сохранение записи в базу данных.
В принципе ничего нет невозможного.
— Вы думаете?
— Для человека. С интеллектом.
— Вы думаете?
— Для человека. С интеллектом.
Re: websocket notification
Нет возможности передать данные из одного процесса в другой, кроме как через внешнее хранилище(например кэш). В этом и проблема.
Если вы все делаете в рамках одно процесса,то проблем нет.
Если вы все делаете в рамках одно процесса,то проблем нет.
2b||!2b Just read the instructions
Re: websocket notification
Появилась новая идея. Из процесса, который что-то сохраняет в базу, подключиться к демону через вебсокет, закинуть туда сообщение и отключиться. Таким образом получится, что не надо внешнее хранилище и пользователи будут уведомлены сразу.vitaxa_prog писал(а): ↑2017.09.12, 13:47 Возникла такая мысль. А можно как то сигнализировать демону WebSocketServer, например из контроллера, что произошло какое то событие? Например сохранение записи в базу данных.
2b||!2b Just read the instructions
- vitaxa_prog
- Сообщения: 306
- Зарегистрирован: 2011.06.06, 22:44
- Откуда: Волноваха
Re: websocket notification
Приходила такая мысль. Но не придумал ничего другого как с помощью curl. А curl не поддерживает протокол ws://
Или можно как то по другому подключиться из процесса, который что-то сохраняет в базу к демону?
В принципе ничего нет невозможного.
— Вы думаете?
— Для человека. С интеллектом.
— Вы думаете?
— Для человека. С интеллектом.
Re: websocket notification
Ну погуглить жеvitaxa_prog писал(а): ↑2017.09.12, 15:48 Или можно как то по другому подключиться из процесса, который что-то сохраняет в базу к демону?
https://packagist.org/search/?q=websocket%20client
https://www.google.ru/search?num=20&new ... FrJEF7c1fE
Предложений море
2b||!2b Just read the instructions
- vitaxa_prog
- Сообщения: 306
- Зарегистрирован: 2011.06.06, 22:44
- Откуда: Волноваха
Re: websocket notification
Да, уж. Голова перестала соображать. Не подумал вообще загуглить "websocket client in php". Видимо отдыхать надо иногда. Спасибо.
Параллельно почитал на http://socketo.me про pusher. Тоже вариант.
Параллельно почитал на http://socketo.me про pusher. Тоже вариант.
В принципе ничего нет невозможного.
— Вы думаете?
— Для человека. С интеллектом.
— Вы думаете?
— Для человека. С интеллектом.
Re: websocket notification
Получилось чего?vitaxa_prog писал(а): ↑2017.09.12, 16:29 Да, уж. Голова перестала соображать. Не подумал вообще загуглить "websocket client in php". Видимо отдыхать надо иногда. Спасибо.
Параллельно почитал на http://socketo.me про pusher. Тоже вариант.
2b||!2b Just read the instructions
- vitaxa_prog
- Сообщения: 306
- Зарегистрирован: 2011.06.06, 22:44
- Откуда: Волноваха
Re: websocket notification
Да. Не было времени. Допилил наконец.
Напишу, может кому пригодится.
Взял вот этот клиент https://github.com/ratchetphp/Pawl
В своей модели Notification в методе afterSave добавил код:
Код: Выделить всё
\Ratchet\Client\connect('ws://site.loc:8080')->then(function($conn) {
$conn->on('message', function($msg) use ($conn) {
//получить ответ от демона и закрыть соединение
//хотя на ответ можно наплевать, клиент не ждет здесь ответа
echo "Received count: {$msg}\n";
$conn->close();
});
//отправить демону запрос(тут можно команду отправлять, это тестовый код)
$conn->send('check_seen='.$this->user_id);
}, function ($e) {
echo "Could not connect: {$e->getMessage()}\n";
});
На сервере(простой эхо сервер пока)
Код: Выделить всё
class EchoServer extends WebSocketServer
{
public function init()
{
parent::init();
$this->on(self::EVENT_CLIENT_MESSAGE, function (WSClientMessageEvent $e) {
//Если получили сообщение на проверку уведомлений, проверяем
if(strpos ($e->message, 'check_seen'))
{
$params = explode('=', $e->message);
$count = Notification::find()->where(['user_id'=>$params[1], 'seen'=>0])->count();
$e->client->send( $count );//отправить сообщение клиенту
echo $count."\n";//посмотреть в консоли что отвечает сервер
}
else
{
//просто отвечаем эхом
$e->client->send( $e->message );
}
});
}
}
Осталось идентифицировать клиенты. Пока не придумал как.
В принципе ничего нет невозможного.
— Вы думаете?
— Для человека. С интеллектом.
— Вы думаете?
— Для человека. С интеллектом.
Re: websocket notification
Правильно я понял, что в первом листинге фрагмент $conn->on('message'... не нужен и надо закрытие ставить сразу после отправки? Здесь же нужно только отправить что-то демону, а не получить. Либо если вы хотите убедиться, что сообщение доставлено и демон ответил эхом, то нужен механизм проверки отсутствия ответа.
Очень рекомендую передавать сообщения в формате json, это очень удобно, решит много проблем и исключит много багов.
Очень рекомендую передавать сообщения в формате json, это очень удобно, решит много проблем и исключит много багов.
2b||!2b Just read the instructions
- vitaxa_prog
- Сообщения: 306
- Зарегистрирован: 2011.06.06, 22:44
- Откуда: Волноваха
Re: websocket notification
Да, если никакие обработки не нужны то можно просто
Код: Выделить всё
\Ratchet\Client\connect('ws://site.loc:8080')->then(function($conn) {
$conn->send('check_seen='.$this->user_id);
$conn->close();
}, function ($e) {
echo "Could not connect: {$e->getMessage()}\n";
});
Да json это правильно. Код который я привел в пример, это набросок на скорую руку. Другими словами говоря - пример как делать не надо)))
В принципе ничего нет невозможного.
— Вы думаете?
— Для человека. С интеллектом.
— Вы думаете?
— Для человека. С интеллектом.
- Ghost_nsk
- Сообщения: 825
- Зарегистрирован: 2012.01.01, 00:45
- Откуда: Новосибирск
- Контактная информация:
Re: websocket notification
у нас реализована связка на одном из проектов - yii2 + node.js + socket.io + redis. Работает более менее адекватно
Re: websocket notification
Круто! Пишите, если будут новые интересные подробности!vitaxa_prog писал(а): ↑2017.09.18, 16:49 Да json это правильно. Код который я привел в пример, это набросок на скорую руку. Другими словами говоря - пример как делать не надо)))
2b||!2b Just read the instructions