2016-08-04 3 views
0

Je commence à déplacer ma webapp de l'application Jetty 9 vers Spring Boot, mais je n'arrive pas à comprendre comment utiliser Jetty WebSocketHandler par opposition à Spring WebSocketHandler et WebSocketSession.Convertir Spring Websocket à Jetty Websocket

Je peux configurer correctement Spring WebSocketHandler dans mon Application.java, et j'ai trouvé les classes JettyWebSocketHandlerAdaptor et JettyWebSocketSession dans la documentation de Spring Framework, mais je n'ai pas été capable de savoir comment l'utiliser ou tout autre bon exemples.

http://docs.spring.io/autorepo/docs/spring-framework/4.1.9.RELEASE/javadoc-api/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.html

Comment puis-je la main sur WebSocketHandler à la jetée? Étant donné que JettyWebSocketAdapter ne dérive d'autre chose que Object, j'ai essayé d'enregistrer un Spring WebSocketHandler, puis toutes ses méthodes se sont transmises à JettyWebSocketHandler. Est-il stupide de ma part de faire cela:

Application.java

@EnableWebSocket 
@SpringBootApplication 
public class Application extends SpringBootServletInitializer implements WebSocketConfigurer { 



    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(Application.class); 
    } 

    @Override 
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 
     SpringWSHandler springPlease = new SpringWSHandler(); 


     registry.addHandler(springPlease, "/websocket").setHandshakeHandler(handshaker()); 
    } 

    @Bean 
    public DefaultHandshakeHandler handshaker() 
    { 
     WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER); 
     policy.setInputBufferSize(8192); 
     policy.setIdleTimeout(600000); 

     return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(new WebSocketServerFactory(policy))); 
    } 


    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Application.class, args); 

    } 
} 

printemps WebSocketHandler

@Component 
public class SpringWSHandler implements WebSocketHandler { 

    private JettyHandler jettyHandler; 
    private JettyWebSocketSession jettySession; 

    private static Logger logger = LoggerFactory.getLogger(SpringWSHandler.class); 



    @Override 
    public void afterConnectionEstablished(WebSocketSession session) throws Exception { 
     logger.debug("Connection Established: " + session.getId()); 
     jettySession = new JettyWebSocketSession(session.getAttributes()); 
     jettyHandler = new JettyHandler(this, jettySession); 
     jettyHandler.onOpen(jettySession.getNativeSession()); 

    } 

    @Override 
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { 
     logger.debug("Message from session: " + session.getId()); 
     jettyHandler.onMessage(message.getPayload().toString()); 

    } 

    @Override 
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { 
     //TODO 

    } 

    @Override 
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { 
     logger.debug("Closing the session: " + session.getId()); 
     jettyHandler.onClose(closeStatus.getCode(), "Closing Connection"); 
     session.close(closeStatus); 
    } 

    @Override 
    public boolean supportsPartialMessages() { 
     return true; 
    } 

} 

Il échoue peu importe depuis quand j'ouvrir ma page web la connexion websocket semble fermer chaque fois J'essaie de l'utiliser. La connexion se ferme une fois que je tente d'utiliser les méthodes de jettyHandler, l'exception est une exception ExceptionWebSocketHandlerDecorator:

11:44:27.530 [qtp1014565006-19] ERROR o.s.w.s.h.ExceptionWebSocketHandlerDecorator - Unhandled error for ExceptionWebSocketHandlerDecorator [delegate=LoggingWebSocketHandlerDecorator [[email protected]]] 
java.lang.NullPointerException: null 

Répondre

0

Soit utiliser WebSocketHandler ou WebSocketHandler de la jetée de printemps directement, ne pas essayer de les mélanger comme ça.

Vous ne pouvez pas utiliser la jetée WebSocketHandler de cette manière, car elle doit faire partie de la hiérarchie Jetty LifeCycle et avoir accès au serveur Jetty pour être sain d'esprit.

Il serait également difficile d'avoir une bonne Jetty WebSocketHandler accéder à la couche de printemps, comme le LifeCycle entre Jetty et Spring ne maillage pas comme ça.

Peut-être que vous pouvez utiliser le WebSocketUpgradeFilter et une implémentation personnalisée de WebSocketCreator pour initialiser le WebSocket que vous visez, avec accès aux couches Spring après le fait.

Votre WebSocketCreator personnalisé sera appelé chaque fois qu'une nouvelle mise à niveau Websocket entrante se produit.

+0

Comment pourriez-vous aller sur l'utilisation WebSocketHandler de la jetée directement? Je ne comprends pas assez Spring pour savoir comment diriger le trafic vers mes Jetty WebSockets. –

0

J'ai réussi à bidouiller quelque chose qui fonctionne pour le moment, mais j'aimerais entendre une méthode meilleure et plus appropriée pour utiliser Jetty WebSockets avec Spring Boot. Cela me permet de passer des messages de Spring WebSocket à ma classe JettyWebSocketHandlerAdapter (JettyHandler) qui transmet le message à ma Jetty WebSocket et aux classes associées.

configuration WebSocketHandler dans Application.java

@Override 
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {   
     SpringWSHandler springPlease = new SpringWSHandler(); 

     registry.addHandler(springPlease, "/websocket").setHandshakeHandler(factoryBean()); 
    } 

    //Configure buffer size and timeouts 
    @Bean 
    public HandshakeHandler factoryBean() 
    { 
     WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER); 
     policy.setInputBufferSize(8192); 
     policy.setIdleTimeout(3600000); 
     WebSocketServerFactory factory = new WebSocketServerFactory(policy); 
     return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(factory)); 
    } 

SpringWSHandler.java

@Component 
public class SpringWSHandler implements WebSocketHandler { 

    private JettyHandler jettyHandler; 
    private JettyWebSocketSession jettySession; 

    private static Logger logger = LoggerFactory.getLogger(SpringWSHandler.class); 



    @Override 
    public void afterConnectionEstablished(WebSocketSession session) throws Exception { 
     //Application.java adapts WebSocket connections to Jetty 9 API when registering handlers with the Jetty handshaker 
     //We can cast spring WebSocketSessions to JettyWebSocketSessions, and initialize the org.eclipse.jetty.websocket.api.Session with itself. 
     jettySession = (JettyWebSocketSession) session; 
     jettySession.initializeNativeSession(jettySession.getNativeSession()); 

     //Setup our custom handler and populate the router, which was magically created by Spring using our annotated classes in Router and its dependencies.  
     jettyHandler = new ClothoJettyHandler(this, jettySession); 

     //Let the jetty web socket commence! 
     jettyHandler.onOpen(jettySession.getNativeSession()); 

    } 

    @Override 
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { 
     logger.debug("Message from session: " + session.getId()); 
     jettyHandler.onMessage(message.getPayload().toString()); 

    } 

    @Override 
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { 
     //TODO 

    } 

    @Override 
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { 
     logger.debug("Closing the session: " + session.getId()); 
     jettyHandler.onClose(closeStatus.getCode(), "Closing Connection"); 
     session.close(closeStatus); 
    } 

    @Override 
    public boolean supportsPartialMessages() { 
     return true; 
    } 

}