Wątek przeniesiony 2018-08-28 15:20 z Off-Topic przez furious programming.

Widget z aktywnością znajomych - jak najlepiej zrobić?

0

Witam, od długich miesięcy pracuję sobie w wolnym czasie nad portalem społecznościowymi, i ostatnio mam małą zagwostkę odnośnie widget-u "Aktywność znajomych", który mam w planach dodać. A więc, zastanawiam się jak go najbardziej wydajnie uzupełniać danymi. Miałby on wyświetlać każdemu użytkownikowi krótkie komunikaty opisujące ostatnie aktywności jego znajomych na portalu, tak jak to miał Facebook niedawno w takim widget-cie nad listą znajomych online:
"Jan Kowalski polubił post."
"Joanna Kowalska skomentowała post."
"Jan Monder odpowiedział na komentarz."
"Kasia Rumień dodała nowe zdjęcie."
"Mariusz Kowalski utworzył album zdjęć.".

Załóżmy, że na portalu będę miał w tym samym momencie 1000 użytkowników online, i oni wszyscy akurat będą na stronie głównej, na której będzie wyświetlał im się ten widget "Aktywność znajomych". Mam zrobione "płynne" przechodzenie między stronami (Ajax), więc ładowanie co odświeżenie strony chyba będzie zbyt sztywne (stare czasy), a no i korzystam tylko z PHP w backendzie (baza: MariaDB). Chciałbym żeby te dane w widget-cie im się odświeżały np. co 1 minutę, no ale Ajax przy 1000 użytkownikach online to bezsens bo serwer padnie.
Myślałem nad NodeJS (który i tak zamierzam użyć do [szybkich] prywatnych wiadomości) do zaciągania tych aktywności i wsadzać je do widget-u, no ale pozostaje jeszcze kwestia samych danych (które mają być wyświetlane w formie komunikatów) - wiadomo, że te lajki, komentarze, albumy zdjęć, zdjęcia, itd. są zapisywane w bazie, tylko jak to sensownie (optymalnie) pobierać do takiego widget-u?
Nie wiem jaką wydajność ma NodeJS na jakimś swoim osobnym serwerku (np. VPS na początek), ale obstawiam, że nie ma sensu męczyć bazy danych co minutę 1000 razy (zapytanie do bazy od NodeJS) i sprawdzać dla każdego użytkownika czy jego znajomi dodali coś nowego (od czasu ostatniego odświeżenia widget-u) - a potem to sortować w JS bo pewnie jednym zapytaniem nie sprawdziłbym wszystkich tabel.
Pewnie niektórzy nie raz już implementowali podobne mechanizmy i może mogą podzielić się jakimś przyjemnym rozwiązaniem do takiego widget-u :D

@mr_jaro liczę, że podpowiesz coś bo kiedyś coś tam mi odpisywałeś w sprawie socketów i cache :)

0

jakieś pomysły? :D

1

Twój model to model "pull" - jestem na stronie, pociągam dane z serwera, prezentuję. Tobie potrzebne jest rozwiązanie w stylu "push" - serwer wypycha dane do subskrybującego klienta. Przyjrzyj się websocketom.

0

O takim modelu właśnie myślałem, tylko jak najlepiej zrobić by serwer wiedział kiedy ma wypchnąć nowe dane do klienta (usera)? Sprawdzać co jakiś czas wszystkie tabele czy są jakieś nowe rekordy dodane i wtedy sprawdzać listy znajomych każdego usera i jeśli jest zdarzenie od jego znajomego to wysyłać mu czy inaczej jakoś to sprawdzać? Takie rozwiązanie nie wydaje mi się za optymalne bo trochę bazę to obciąży i to często.
Może do oddzielnej tabeli zapisywać kazde nowe zdarzenie to wtedy mniejsze obciążenie będzie przy zaciąganiu danych z bazy bo nie będzie musiało sprawdzać wielu tabel a tylko tą jedną, tylko pozostaje nadal kwestia sprawdzania czy to usera znajomy dodał dane zdarzenie (żeby było wiadomo czy ma mu dane zdarzenie wyswietlic).

0

Znowu myślisz w modelu pull, tylko warstwę niżej ;) Powiadomienia o których mówisz można realizować na skutek konkretnych operacji w systemie. Jeśli w twojej aplikacji używasz np. eventów, to w momencie wysłania eventu "PhotoUploaded" możesz w innym module (np. odpowiedzialnym za powiadomienia) odebrać taki event i wysłać odpowiednie powiadomienie do subskrybujących klientów. Co prawda zazwyczaj siedzę w warstwach bliżej klienta, ale tak bym sobie to wyobrażał.

User wrzuca zdjęcie -> generuje się event PhotoUploaded -> event jest rejestrowany w określonym module (kolejce, etc.) -> inny moduł subskrybujący np. kolejkę może zareagować i wysłać powiadomienie

screenshot-20180831164145.png

1 użytkowników online, w tym zalogowanych: 0, gości: 1