2016-08-04 15 views
0

Ich beginne meine vorhandene Jetty 9 Webapp-Anwendung auf Spring Boot zu verschieben, aber ich kann nicht herausfinden, wie Sie einen Jetty WebSocketHandler im Gegensatz zu einem Spring WebSocketHandler und WebSocketSession verwenden.Konvertieren von Spring Websocket in Jetty Websocket

Ich kann den Spring WebSocketHandler in meiner Application.java ordnungsgemäß einrichten, und ich fand die JettyWebSocketHandlerAdaptor und die JettyWebSocketSession-Klassen in der Spring Framework-Dokumentation, aber ich konnte nicht herausfinden, wie man es oder etwas Gutes verwendet Beispiele.

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

Wie gebe ich die WebSocketHandler auf Anlegestelle über? Da der JettyWebSocketAdapter nicht von etwas anderem als Object abgeleitet ist, habe ich versucht, einen Spring WebSocketHandler zu registrieren und dann alle seine Methoden selbst an einen JettyWebSocketHandler übergeben zu lassen. Ist es von mir dumm tun dies zu:

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); 

    } 
} 

Frühling 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; 
    } 

} 

Es schlägt fehl, unabhängig nach, da ich meine Webseite öffnen die websocket Verbindung zu schließen scheint, wann immer Ich versuche es zu benutzen. Die Verbindung wird geschlossen, sobald ich versuche, jettyHandler Methoden zu verwenden, die Ausnahme ist eine ExceptionWebSocketHandlerDecorator Ausnahme:

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 

Antwort

0

Entweder direkt Spring WebSocketHandler oder Jetty des WebSocketHandler verwenden, versuchen Sie nicht, sie so zu mischen.

Sie können den Jetty WebSocketHandler nicht auf diese Weise verwenden, da er Teil der Jetty LifeCycle-Hierarchie sein muss und Zugriff auf den Jetty-Server haben muss.

Es wäre auch schwierig, einen richtigen Jetty WebSocketHandler Zugriff auf die Spring-Ebene zu haben, da der LifeCycle zwischen Jetty und Spring nicht so ineinandergreifen.

Vielleicht können Sie die WebSocketUpgradeFilter und eine benutzerdefinierte Implementierung von WebSocketCreator verwenden, um den WebSocket zu initialisieren, den Sie anstreben, komplett mit Zugang zu den Spring-Schichten nach der Tat.

Ihre benutzerdefinierte WebSocketCreator wird jedes Mal aufgerufen, wenn eine neue eingehende Websocket-Aktualisierung auftritt.

+0

Wie konnten Sie direkt Jetty der WebSocketHandler gehen über die Verwendung? Ich verstehe Spring nicht gut genug, um wirklich zu wissen, wie man den Traffic zu meinen Jetty WebSockets leitet. –

0

Ich habe es geschafft, etwas zusammen zu hacken, das vorerst funktioniert, würde aber gerne eine bessere und geeignetere Methode zur Verwendung von Jetty WebSockets mit Spring Boot hören.

Dadurch kann ich Nachrichten aus dem Spring WebSocket an meine JettyWebSocketHandlerAdapter (JettyHandler) -Klasse übergeben, die die Nachricht an meine Jetty WebSocket und zugeordneten Klassen übergibt.

WebSocketHandler Einrichtung in 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; 
    } 

}