带有 Spring Boot 的 JAVAX JSR 356 Websocket

Posted

技术标签:

【中文标题】带有 Spring Boot 的 JAVAX JSR 356 Websocket【英文标题】:JAVAX JSR 356 Websocket with Spring Boot 【发布时间】:2018-08-15 12:20:25 【问题描述】:

我正在尝试在 Spring Boot 项目中使用 Javax JSR 356 API 实现服务器端 websocket 端点。我正在关注this 教程。我知道关于这个主题有一些关于 SO 的问题,但我找不到合理的解决方案。当我尝试使用客户端 (ARC) 连接到 websocket 时,它只会报告“发生未知错误”。我检查了嵌入式 Tomcat 服务器的日志,但没有任何条目。根据Tomcat启动条目,应用程序的上下文路径为空(“”),所以我确定我使用正确的URI访问了websocket。

这是我的代码:

@ServerEndpoint(value = "/socket", configurator = SpringConfigurator.class)
public class WebSocketController

    @OnOpen
    public void onOpen(Session session) throws IOException
    
        System.out.println("Socket has been opened: " + session.getId());
    

    @OnClose
    public void onClose(Session session) throws IonException
    
        System.out.println("Socket has been closed: " + session.getId());
    


Spring configuration class
@Configuration
public class WebSocketConfig

    @Bean
    public WebSocketController webSocketController()
    
        return new WebSocketController();
    

    @Bean
    public ServletContextAware endpointExporterInitializer(final ApplicationContext applicationContext) 
        return new ServletContextAware() 

            @Override
            public void setServletContext(ServletContext servletContext) 
                ServerEndpointExporter serverEndpointExporter = new ServerEndpointExporter();
                serverEndpointExporter.setApplicationContext(applicationContext);
                try 
                    serverEndpointExporter.afterPropertiesSet();
                 catch (Exception e) 
                    throw new RuntimeException(e);
                
            
        ;
    

如何在 Spring Boot 应用程序中实现服务器端 websocket 端点?

更新: 按照第一个答案后,Tomcat服务器的日志。它一开始就停止。

2018-08-16 00:16:37.160  INFO 12944 --- [           main] o.s.w.s.s.s.ServerEndpointExporter       : Registering @ServerEndpoint class: class io.ai.vivid.zen.controller.WebSocketController
2018-08-16 00:16:37.169  INFO 12944 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2018-08-16 00:16:37.170 DEBUG 12944 --- [cat-startStop-1] o.apache.catalina.mapper.MapperListener  : Unregister host [localhost] at domain [null] for service [StandardService[Tomcat]]
2018-08-16 00:16:37.170 DEBUG 12944 --- [ost-startStop-1] o.apache.catalina.mapper.MapperListener  : Unregister Context [] for service [StandardService[Tomcat]]
2018-08-16 00:16:37.170 DEBUG 12944 --- [ost-startStop-1] o.apache.catalina.mapper.MapperListener  : Unregister Wrapper [default] in Context [] for service [StandardService[Tomcat]]
2018-08-16 00:16:37.170 DEBUG 12944 --- [ost-startStop-1] o.apache.catalina.mapper.MapperListener  : Unregister Wrapper [dispatcherServlet] in Context [] for service [StandardService[Tomcat]]
2018-08-16 00:16:37.170 DEBUG 12944 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Stopping filters
2018-08-16 00:16:37.170 DEBUG 12944 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       :  Stopping filter 'requestContextFilter'
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.core.ApplicationFilterConfig       : JMX de-registration complete for filter of type [org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter] and name [requestContextFilter]
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       :  Stopping filter 'Tomcat WebSocket (JSR356) Filter'
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.core.ApplicationFilterConfig       : JMX de-registration complete for filter of type [org.apache.tomcat.websocket.server.WsFilter] and name [Tomcat WebSocket (JSR356) Filter]
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       :  Stopping filter 'httpPutFormContentFilter'
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.core.ApplicationFilterConfig       : JMX de-registration complete for filter of type [org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter] and name [httpPutFormContentFilter]
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       :  Stopping filter 'hiddenHttpMethodFilter'
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.core.ApplicationFilterConfig       : JMX de-registration complete for filter of type [org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter] and name [hiddenHttpMethodFilter]
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       :  Stopping filter 'characterEncodingFilter'
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.c.core.ApplicationFilterConfig       : JMX de-registration complete for filter of type [org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter] and name [characterEncodingFilter]
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.catalina.session.StandardManager     : Stopping
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.catalina.session.StandardManager     : Unloading persisted sessions
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.a.catalina.session.StandardManager     : No persisted sessions to unload
2018-08-16 00:16:37.171 DEBUG 12944 --- [ost-startStop-1] o.apache.catalina.core.StandardContext   : Sending application stop events
2018-08-16 00:16:37.172 DEBUG 12944 --- [ost-startStop-1] o.apache.catalina.core.StandardContext   : Processing standard container shutdown
2018-08-16 00:16:37.172 DEBUG 12944 --- [ost-startStop-1] org.apache.catalina.loader.WebappLoader  : Stopping this Loader
2018-08-16 00:16:37.172 DEBUG 12944 --- [ost-startStop-1] o.a.c.loader.WebappClassLoaderBase       : getResourceAsStream(org/apache/catalina/loader/JdbcLeakPrevention.class)
2018-08-16 00:16:37.172 DEBUG 12944 --- [ost-startStop-1] o.a.c.loader.WebappClassLoaderBase       :   Delegating to parent classloader jdk.internal.loader.ClassLoaders$AppClassLoader@28c97a5
2018-08-16 00:16:37.175 DEBUG 12944 --- [ost-startStop-1] o.a.c.loader.WebappClassLoaderBase       :   --> Returning stream from parent
2018-08-16 00:16:37.183 DEBUG 12944 --- [ost-startStop-1] o.apache.catalina.core.StandardContext   : resetContext Tomcat:j2eeType=WebModule,name=//localhost/,J2EEApplication=none,J2EEServer=none
2018-08-16 00:16:37.183 DEBUG 12944 --- [ost-startStop-1] o.apache.catalina.core.StandardContext   : Stopping complete

【问题讨论】:

【参考方案1】:

我的 Websocket 配置是这样工作的:

@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer 

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) 
        //registry.addHandler(unitWebSocketHandler, "/unit").setAllowedOrigins("*");
    

    @Bean
    public WebSocketController webSocketController() 
        return new WebSocketController();
    

    @Bean
    public ServerEndpointExporter serverEndpointExporter() 
        return new ServerEndpointExporter();
    

然后删除configurator = SpringConfigurator.class

所以你的端点看起来像这样:

@ServerEndpoint(value = "/socket")
public class WebSocketController

示例项目在 GitHub 上可用: https://github.com/simasch/spring-boot-websocket

【讨论】:

因为我的代码中没有使用WebSocketHandlerRegistry添加处理程序,所以Tomcat服务器在启动后立即停止。 registerWebSocketHandlers 方法中应该指定什么? 正如我所说的那样,这很有效。你发现有什么例外吗? 没有例外。我已经发布了 Tomcat 服务器的日志输出。请看一看。 您使用的是哪个版本的 Spring Boot? Spring Boot 版本 2.0.4.RELEASE

以上是关于带有 Spring Boot 的 JAVAX JSR 356 Websocket的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Boot 如何正确注入 javax.validation.Validator

Spring Boot 发送邮件 javax.mail

没有可用的“javax.sql.DataSource”类型的合格bean - spring-boot-batch

Spring Boot 中的 javax.validation.constraints.Email

Spring Boot 应用程序中的 javax.servlet

Spring boot ---- java.lang.NoClassDefFoundError: javax/servlet/ServletContext