Ich verwende SimpUserRegistry
, um eine Online-Benutzeranzahl zu erhalten (mit getUserCount()
). Und es funktioniert gut auf meinen lokalen Maschinen, aber nicht auf AWS EC2-Instanzen (versucht mit Amazon Linux und Ubuntu) mit nur elastischer IP und ohne Lastausgleich.
Das Problem an EC2 ist, dass einige Benutzer, wenn sie verbunden sind, niemals zur Registrierung hinzugefügt werden und dadurch falsche Ergebnisse erhalten.
Ich habe Sitzung Listener, für SessionConnectedEvent
und SessionDisconnectEvent
, wo ich die SimpUserRegistry
(autowired) verwenden, um die Benutzerpräsenz zu erhalten. Wenn es darauf ankommt, bin ich auch SimpUserRegistry
ist ein Messaging Controller.
Unten ist der Websocket Message Broker config:
%Vor%Und unten ist der Kanalabfanger, der in der obigen Konfigurationsklasse verwendet wird:
%Vor%Ich habe auch folgende geplante Aufgabe, die einfach die Benutzernamen alle zwei Sekunden ausgibt:
%Vor%Und einige Benutzernamen werden niemals angezeigt, selbst wenn sie verbunden sind.
Die Implementierung von SecurityService
class -
Aktualisieren
Nachfolgend finden Sie ein Beispiel von SockJS Log-in Browser -
Richtige Antwort vom Server mit user-name
header:
Falsche Antwort vom Server ohne user-name
header:
Ich habe auch überprüft, dass SecurityChannelInterceptor
alle Benutzer authentifiziert, auch wenn user-name
nicht in der CONNECTED
-Antwort enthalten ist.
Aktualisieren
Ich habe die App auf Heroku bereitgestellt. Und das Problem passiert auch dort.
Aktualisieren
Wenn das Problem auftritt, ist user
in SessionConnectEvent
der Wert, der von SecurityChannelInterceptor
gesetzt wird, aber user
in SessionConnectedEvent
ist null
.
Aktualisieren
AppAuth
class -
Ich konnte das Problem nach dem Debuggen verfolgen, indem ich ein paar Logger-Anweisungen in StompSubProtocolHandler
hinzufügte.
Nach dem Auffinden der Ursache war die Schlussfolgerung, dass ein Kanal-Interzeptor kein korrekter Ort ist, um einen Benutzer zu authentifizieren. Zumindest für meinen Anwendungsfall.
Nachfolgend finden Sie einige Code-Snippets von StompSubProtocolHandler
-
Die Methode handleMessageFromClient
fügt den Benutzer der Karte stompAuthentications
hinzu und veröffentlicht ein SessionConnectEvent
-Ereignis -
Und die handleMessageToClient
ruft den Benutzer von der stompAuthentications
Karte ab und veröffentlicht eine SessionConnectedEvent
-
getUser
-Methode, die von obigen Methoden verwendet wird -
Nun tritt das Problem auf, wenn der handleMessageToClient
-Snippet vor dem handleMessageFromClient
-Snippet ausgeführt wird. In diesem Fall wird der Benutzer niemals zu DefaultSimpUserRegistry
hinzugefügt, da nur die SessionConnectedEvent
überprüft wird.
Nachfolgend finden Sie das Ereignis-Listener-Snippet von DefaultSimpUserRegistry
-
Lösung
Die Lösung, die mir hilft, ist es, DefaultHandshakeHandler
und überschreiben Sie die Methode determineUser
, die auf diese Antwort . Da ich SockJS verwende, muss der Client jedoch auth-token als Abfrageparameter senden. Und der Grund für die Abfrageparameteranforderung wird hier besprochen.
Nur einige Punkte, die Ihnen bei der Lösung des Problems helfen können.
Für einige Benutzer wird eindeutig authentication
nicht gesetzt. Hast du irgendein Muster bemerkt, in welchem Zustand der authentication
nicht gesetzt ist? Gehen Sie durch den Quellcode von DefaultSimpUserRegistry und StompSubProtocolHandler bestätigt, dass authentication/principle
für einige Benutzer nicht festgelegt wurde. Aus diesem Grund fehlen Benutzer in SimpUserRegistry.
Gehen Sie durch - Websocket-Authentifizierung und Autorisierung im Frühjahr . Es wird vorgeschlagen, dass die authentication
möglicherweise nicht gesetzt wird, wenn GrantedAuthorities
in authentication/principle
fehlt.
Sie können wahrscheinlich die Erstellung Ihres AppAuth
-Objekts überprüfen und prüfen, ob die GrantedAuthorities
für alle Benutzer richtig eingestellt ist.
Ich hoffe, dass dies bei der Lösung Ihres Problems helfen kann.
Tags und Links java websocket spring-websocket amazon-ec2 spring-messaging