Table of Contents

Class OnlineTracker

Namespace
UsluzionicaServer.Infrastructure
Assembly
UsluzionicaServer.dll

Praćenje online korisnika i njihovih SignalR konekcija.

ZAŠTO OVO MORA U REDIS: SignalR konekcija je vezana za JEDAN proces. Sa dve instance API-ja iza load balancera, Ana je konektovana na instancu A, Marko na instancu B. Kad Marko otvori listu razgovora, njegov zahtev obrađuje instanca B — koja u svojoj memoriji nema pojma o Aninoj konekciji i prikaže je kao offline. Uvek.

Redis drži to stanje van procesa, pa obe instance vide isto.

STRUKTURA: Redis SET po korisniku. usluzionica:online:{userId} → { connectionId1, connectionId2, ... } Skup jer isti korisnik može biti prijavljen sa telefona i sa laptopa istovremeno — offline je tek kad NIJEDNA konekcija ne ostane.

TTL na ključu je zaštita od procesa koji padne: OnDisconnectedAsync se tada nikad ne izvrši i connectionId bi zauvek ostao u skupu, pa bi korisnik večno bio „online". TTL se obnavlja pri svakoj registraciji.

FALLBACK: bez Redis-a radi tačno kao pre — ConcurrentDictionary u memoriji. To je ispravno za jednu instancu i drži testove zelenim.

public sealed class OnlineTracker
Inheritance
OnlineTracker
Inherited Members

Constructors

OnlineTracker(RedisConnection, ILogger<OnlineTracker>)

Praćenje online korisnika i njihovih SignalR konekcija.

ZAŠTO OVO MORA U REDIS: SignalR konekcija je vezana za JEDAN proces. Sa dve instance API-ja iza load balancera, Ana je konektovana na instancu A, Marko na instancu B. Kad Marko otvori listu razgovora, njegov zahtev obrađuje instanca B — koja u svojoj memoriji nema pojma o Aninoj konekciji i prikaže je kao offline. Uvek.

Redis drži to stanje van procesa, pa obe instance vide isto.

STRUKTURA: Redis SET po korisniku. usluzionica:online:{userId} → { connectionId1, connectionId2, ... } Skup jer isti korisnik može biti prijavljen sa telefona i sa laptopa istovremeno — offline je tek kad NIJEDNA konekcija ne ostane.

TTL na ključu je zaštita od procesa koji padne: OnDisconnectedAsync se tada nikad ne izvrši i connectionId bi zauvek ostao u skupu, pa bi korisnik večno bio „online". TTL se obnavlja pri svakoj registraciji.

FALLBACK: bez Redis-a radi tačno kao pre — ConcurrentDictionary u memoriji. To je ispravno za jednu instancu i drži testove zelenim.

Methods

GetConnectionsAsync(string)

Snapshot connectionId-ova za datog korisnika.

IsOnlineAsync(string)
RegisterAsync(string, string)

Registruje novu konekciju pri OnConnectedAsync.

UnregisterAsync(string, string)

Uklanja konekciju pri OnDisconnectedAsync. Vraća true ako je korisnik POTPUNO offline (nema više nijedne konekcije).

WhoIsOnlineAsync(IEnumerable<string>)

Online status za VIŠE korisnika odjednom.

Postoji zbog liste razgovora: ona prolazi kroz N sagovornika, i poziv IsOnlineAsync(string) u petlji bi značio N odvojenih mrežnih obilazaka do Redis-a. Ovde sve ide kao jedan batch — biblioteka ih spakuje u jedan pipeline i čeka sve odgovore zajedno.