项目中有websocket时部署的问题

发布时间 2023-05-23 11:01:18作者: 周文豪

一、websockt部署报错Error creating bean with name 'serverEndpointExporter'

启动后台报错:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverEndpointExporter' defined in class path resource [com/ljxx/common/config/WebSocketConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.24.jar:5.3.24]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.24.jar:5.3.24]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.6.jar:2.7.6]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.6.jar:2.7.6]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.6.jar:2.7.6]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.6.jar:2.7.6]
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175) [spring-boot-2.7.6.jar:2.7.6]
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155) [spring-boot-2.7.6.jar:2.7.6]
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97) [spring-boot-2.7.6.jar:2.7.6]
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174) [spring-web-5.3.24.jar:5.3.24]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5135) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.24]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717) [catalina.jar:9.0.24]
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690) [catalina.jar:9.0.24]
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705) [catalina.jar:9.0.24]
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:978) [catalina.jar:9.0.24]
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1849) [catalina.jar:9.0.24]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_331]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_331]
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-util.jar:9.0.24]
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) [na:1.8.0_331]
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:773) [catalina.jar:9.0.24]
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:427) [catalina.jar:9.0.24]
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576) [catalina.jar:9.0.24]
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) [catalina.jar:9.0.24]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:936) [catalina.jar:9.0.24]
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.24]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) [catalina.jar:9.0.24]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) [catalina.jar:9.0.24]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_331]
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-util.jar:9.0.24]
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) [na:1.8.0_331]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) [catalina.jar:9.0.24]
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.24]
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.24]
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:932) [catalina.jar:9.0.24]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.24]
    at org.apache.catalina.startup.Catalina.start(Catalina.java:633) [catalina.jar:9.0.24]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_331]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_331]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_331]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_331]
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:344) [bootstrap.jar:9.0.24]
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:475) [bootstrap.jar:9.0.24]
Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
    at org.springframework.util.Assert.state(Assert.java:76) ~[spring-core-5.3.24.jar:5.3.24]
    at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterPropertiesSet(ServerEndpointExporter.java:107) ~[spring-websocket-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.24.jar:5.3.24]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.24.jar:5.3.24]
    ... 57 common frames omitted

解决办法:

将@Bean注解注释掉

//开启WebSocket的支持,并把该类注入到spring容器中
@Configuration
@ConditionalOnProperty(name = "system.websocket.isOpen",havingValue = "true")
public class WebSocketConfig {

    // @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

ServerEndPointExporter在springboot内置容器(嵌入式容器)中运行时,必须上下文提供ServerEndpointExporter;但是在tomcat容器中运行时,扫描工作会交给容器处理,不需要bean注入。故在开发环境需要ServerEndpointExporter对象,但在测试环境或生产环境中部署到tomcat中时,需要将该对象注释掉。

二、前端websocket通过nginx转发时的配置

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;


    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       84;
        server_name  127.0.0.1;

        location / {
            root  D:/project/prism/nodePlatform/hainan-web/dist;
            try_files $uri $uri/ /index.html;

        }

        location ~^/api/ {        
            proxy_pass  http://127.0.0.1:8011;
            proxy_read_timeout 600s; #默认是60s,若不配置则超过60s会出现504状态码
        }


        location ~^/wsServer/ {
            proxy_pass http://127.0.0.1:8011;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
             proxy_read_timeout 36000s; #10小时未传输数据则关闭连接
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}