2016-08-04 8 views
0

Я начинаю перемещать существующее приложение Jetty 9 webapp в Spring Boot, но я не могу понять, как использовать Jetty WebSocketHandler, а не Spring WebSocketHandler и WebSocketSession.Преобразование Spring Websocket в Jetty Websocket

Я могу правильно настроить Spring WebSocketHandler в своем приложении Application.java, и я нашел классы JettyWebSocketHandlerAdaptor и JettyWebSocketSession в документации Spring Framework, но я не смог узнать, как ее использовать или любой хороший Примеры.

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

Как передать WebSocketHandler в Jetty? Поскольку JettyWebSocketAdapter не происходит ни от чего, кроме Object, я пытаюсь зарегистрировать Spring WebSocketHandler, а затем просто все методы передаются на JettyWebSocketHandler. Это глупо мне делать это:

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

    } 
} 

Spring 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; 
    } 

} 

Это не может независимо, так как после того, как я открываю мою веб-страницу соединения WebSocket, кажется, чтобы закрыть, когда Я пытаюсь использовать его. Соединение закрывается, как только я пытаюсь использовать методы jettyHandler, то исключением является исключением 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 

ответ

0

Либо использовать Spring в WebSocketHandler или WebSocketHandler Jetty напрямую, не пытаться смешивать их, как это.

Вы не можете использовать Jetty WebSocketHandler таким образом, поскольку он должен быть частью иерархии Jetty LifeCycle и иметь доступ к серверу Jetty, чтобы он был нормальным.

Также было бы сложно получить подходящий Jetty WebSocketHandler доступ к слою Spring, так как LifeCycle между Jetty и Spring не имеет такой сетки.

Возможно, вы можете использовать WebSocketUpgradeFilter и пользовательскую реализацию WebSocketCreator для инициализации WebSocket, к которому вы стремитесь, в комплекте с доступом к слоям Spring после факта.

Ваш пользовательский WebSocketCreator будет называться каждый раз, когда происходит обновление нового входящего веб-узла.

+0

Как вы могли бы идти об использовании WebSocketHandler Jetty напрямую? Я не понимаю Spring достаточно хорошо, чтобы действительно знать, как направлять трафик на мои Jetty WebSockets. –

0

Мне удалось взломать что-то, что работает на данный момент, но хотелось бы услышать лучший и более подходящий метод использования Jetty WebSockets с Spring Boot.

Это позволяет передавать сообщения из Spring WebSocket в класс JettyWebSocketHandlerAdapter (JettyHandler), который передает это сообщение на мой Jetty WebSocket и связанные классы.

установка WebSocketHandler в 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; 
    } 

}