newpdv
@newpdv
Web-devekioer

Как организована система оповещений а-ля Вконтакте?

Как организована система оповещений, например контакта?

Список событий (новое сообщение, новый друг, новый подарок) хранятся в отдельной базе и по аяксу извлекаются каждые n-секунд или по другому?

У кого какие мысли, и как лучше организовать?
  • Вопрос задан
  • 13815 просмотров
Пригласить эксперта
Ответы на вопрос 6
goshakkk_reborn
@goshakkk_reborn
Скорее паттерн Publish-subscribe. Фронт-энд подписывается на какой-то тип сообщений на каком-то канале (например, new-message, new-friendship-request, new-gift на канале user-ID) и выполняет какие-то действия с данными этих сообщений (обновляет счетчик непрочитанных сообщение, делает новое уведомление через Web Notifications API, что угодно). А сервер, помимо записи данных в базу, отправляет новое сообщение какого-то типа на конкретный канал.

Т.е. кто-то отправил новое сообщение. Сервер пишет его в базу и пушит на клиент:

message = Message.create params[:message]
Pusher["user-#{message.receiver.id}"].trigger('new-message', message)


Клиент просто слушает и что-то делает с данными:

var channel = pusher.subscribe('user-500fbf726446c604d2000001');
channel.bind('new-message', function(data) {
  alert('Received new message from ' + data.sender.name + ': ' + data.text)
});


Посмотрите в сторону Web Sockets — socket.io/faye (если хочется у себя держать) или pusher (если хочется все это просто делать через сервис).
Ответ написан
@egorinsk
У вас же браузер есть. Заходим на vk.com и видим, что, например, в Опере, шлются long-polling запросы на qNN.queue.vk.com/im305, куда посылается id пользователя, хитрый ключ, временные метки, в ответ приходит код вида ([{«ts»:«1567120607»,«events»:[]}

Очевидно, у них развернута сеть серверов, на которых висят демоны, не знаю, на какой технологии, может Си, может Node.JS, может еще что-то, которые, с одной стороны, принимают запросы от клиентов, с другой стороны, получают уведомления.

Думаю, в коде проще всего при каком-то событии (например, отправка сообщения/добавление в друзья) параллельно этому демону посылается уведомление, и он ретранслирует это обновление заинтересованным пользователям.

Если бы мне нужен был такой демон, я бы взял для разработки язык D и библиотеку libev.

Но вы можете попробовать такой демон на PHP написать, я думаю, 10-20 одновременных пользователей он точно выдержит. Или можете взять уже готовый демон — PHP Multiplexor или как-то так, от DKLab.
Ответ написан
ilyaplot
@ilyaplot
PHP программист
Видел на хабре кроссбраузерное решение — опрос файла, отдаваемого легким web сервером с чтением заголовка modified. Если изменен — читаем. И зачем держать множество постоянных соединений?
Ответ написан
ohmytribe
@ohmytribe
Судя по всему, тут как раз подписка на события. Посмотрел через девелопер тулс — раз в несколько секунд отсылается запрос со списком id и временем ожидания (как я понимаю, чем выше моя активность, тем меньше время ожидания):
ts:1233434603_12354100_1238569453 wait:25

Обратно получаю:
[{"ts":"1233434603","events":[]},{"ts":"13254101","events":[]},{"ts":"1238569454","events":[]}]
Ответ написан
@tsegorah
возможно вам поможет паттерн наблюдатель (observer), попробуйте посмотреть в эту сторону.
Ответ написан
vermilion1
@vermilion1
Лучше использовать лонгпулинг в случаи если вам нужно тут же показать пользователю уведомление, ну или каждые Н секунд дергать сервер. Делаете запрос на сервер «дай мне новых друзей» и если таковых нету — держать соединение открытым, а закрыть или по таймауту или когда появится друг. Повторить.
Не могу проверить как работает контакт, так как не за компьютером, но скорей всего там используется лонгпулинг
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы