首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Spring Websocket转换为Jetty Websocket

将Spring Websocket转换为Jetty Websocket
EN

Stack Overflow用户
提问于 2016-08-04 23:33:02
回答 2查看 3.2K关注 0票数 1

我开始将我现有的Jetty9应用程序webapp迁移到Spring Boot上,但我似乎不知道如何使用Jetty WebSocketHandler,而不是Spring WebSocketHandler和WebSocketSession。

我可以在我的Application.java中正确地设置Spring WebSocketHandler,我在Spring Framework文档中找到了JettyWebSocketHandlerAdaptor和JettyWebSocketSession类,但我还没有找到如何使用它或任何好的示例。

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

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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;
    }

}

它失败了,因为在我打开我的网页后,每当我试图使用它时,网页套接字连接似乎都会关闭。一旦我尝试使用jettyHandler的方法,连接就会关闭,异常是一个ExceptionWebSocketHandlerDecorator异常:

代码语言:javascript
复制
11:44:27.530 [qtp1014565006-19] ERROR o.s.w.s.h.ExceptionWebSocketHandlerDecorator - Unhandled error for ExceptionWebSocketHandlerDecorator [delegate=LoggingWebSocketHandlerDecorator [delegate=org.appcad.webserver.jetty.SpringWSHandler@5a7b309b]]
java.lang.NullPointerException: null
EN

回答 2

Stack Overflow用户

发布于 2016-08-05 01:58:58

直接使用Spring的WebSocketHandler或Jetty的WebSocketHandler,不要尝试将它们混合在一起。

您不能以这种方式使用Jetty WebSocketHandler,因为它需要是Jetty LifeCycle层次结构的一部分,并且能够正常访问Jetty Server。

让一个合适的Jetty访问Spring层也是很困难的,因为Jetty和WebSocketHandler之间的LifeCycle不会像那样融合在一起。

也许您可以使用WebSocketUpgradeFilterWebSocketCreator的自定义实现来初始化您的目标WebSocket,并在完成后访问Spring层。

您的自定义WebSocketCreator将在每次发生新的传入websocket升级时被调用。

票数 1
EN

Stack Overflow用户

发布于 2016-08-05 04:12:59

我已经设法破解了一些暂时有效的东西,但我希望听到一个更好、更合适的方法来使用Jetty WebSockets和Spring Boot。

这允许我将消息从Spring传递到我的JettyWebSocketHandlerAdapter (JettyHandler)类,后者将消息传递给我的WebSocket WebSocket和相关的类。

Application.java中的WebSocketHandler设置

代码语言:javascript
复制
    @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

代码语言:javascript
复制
@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;
    }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38771666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档