web-dev-qa-db-fra.com

Déconnecter la session cliente du serveur d'instance Websocket Spring

J'ai cherché un peu et n'ai pas pu trouver ceci: Y a-t-il un moyen qu'un serveur de stomp de websocket de ressort puisse déconnecter un client basé sur le sessionId (ou vraiment basé sur n'importe quoi du tout)? 

Il me semble qu'une fois qu'un client se connecte à un serveur, rien ne permet au serveur de déconnecter le client.

15
user1751547

Autant que je sache, l'API ne fournit pas ce que vous recherchez, côté serveur, vous ne pouvez détecter que les événements de déconnexion. Si vous souhaitez déconnecter un certain client, je pense que vous devez opter pour une solution de contournement, par exemple. celui-là:

  1. Écrire une fonction javascript côté client pouvant déclencher une déconnexion 
  2. Dès que votre client est connecté au serveur, générez un identifiant client dans votre javascript et envoyez-le au serveur. Rappelez-vous l'ID sur le client, vous en aurez besoin à l'étape (4).
  3. Lorsque vous souhaitez que le serveur déconnecte la connexion au client spécifique (identifié par l'ID), envoyez un message contenant l'ID au client.
  4. Maintenant, votre client javascript évalue le message envoyé par le serveur et décide d'appeler la fonction de déconnexion que vous avez écrite à l'étape (1). 
  5. Votre client se déconnecte.

La solution de contournement est un peu lourde mais ça va marcher.

1
mika

En fait, en utilisant certaines solutions de contournement, vous pouvez obtenir ce que vous voulez. Pour cela, vous devriez faire:

  1. Utiliser la configuration Java (pas sûr si c'est possible avec XML config)
  2. Étendez votre classe de configuration à partir de WebSocketMessageBrokerConfigurationSupport et implémentez WebSocketMessageBrokerConfigurer interface
  3. Créez un gestionnaire de websocket de sous-protocole personnalisé et étendez-le à partir de SubProtocolWebSocketHandler class
  4. Dans votre sous-protocole personnalisé, le gestionnaire websocket remplace afterConnectionEstablished et vous aurez accès à WebSocketSession :)

J'ai créé un exemple de projet Spring-Boot pour montrer comment nous pouvons déconnecter une session client côté serveur: https://github.com/isaranchuk/spring-websocket-disconnect

11
isaranchuk

Vous pouvez également déconnecter une session en implémentant une WebSocketHandlerDecorator personnalisée:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig<S extends ExpiringSession> extends AbstractSessionWebSocketMessageBrokerConfigurer<S> {

    @Override
    public void configureWebSocketTransport(final WebSocketTransportRegistration registration) {
        registration.addDecoratorFactory(new WebSocketHandlerDecoratorFactory() {
            @Override
            public WebSocketHandler decorate(final WebSocketHandler handler) {
                return new WebSocketHandlerDecorator(handler) {
                    @Override
                    public void afterConnectionEstablished(final WebSocketSession session) throws Exception {

                        session.close(CloseStatus.NOT_ACCEPTABLE);
                        super.afterConnectionEstablished(session);
                    }
                };
            }
        });
        super.configureWebSocketTransport(registration);
    }


    @Override
    protected void configureStompEndpoints(final StompEndpointRegistry registry) {
    registry.addEndpoint("/home")
            .setHandshakeHandler(new DefaultHandshakeHandler(
                    new UndertowRequestUpgradeStrategy() // If you use undertow
                    // new JettyRequestUpgradeStrategy()
                    // new TomcatRequestUpgradeStrategy()
            ))
            .withSockJS();
    }
}
4
Dániel Kis

En cas de configuration XML, vous pouvez utiliser <websocket:decorator-factories> dans le <websocket:transport> de votre <websocket:message-broker>. Créez les personnalités WebSocketHandlerDecorator et WebSocketHandlerDecoratorFactory qui implémentent la méthode decorate

0