zoukankan      html  css  js  c++  java
  • Springboot使用外置tomcat的同时使用websocket通信遇到的坑

    如果使用JAR包部署,直接使用现成的代码和注解配置就可以使用了。但是由于我们项目文件是上传到服务器本项目一个目录下,JAR包每次开机需要启动,这样每次又是开启一个新的tomcat来跑项目,导致文件一旦服务器重启就会找不到。所以考虑使用WAR包部署

    但是在打WAR包的时候,由于使用的是外置的tomcat,需要移除掉Springboot内置的Tomcat服务。

    但是这样就会报@ServerEndPoint的错误,主要就是依赖的jar包是从tomcat里获取的,我们把内置的tomcat移除了使用外置的,便会得不到其中相关的jar包。解决方法其实很简单,就是在pom里引入这个丢失的jar包即可。

            <dependency>
                <groupId>javax.websocket</groupId>
                <artifactId>javax.websocket-api</artifactId>
                <version>1.1</version>
                <scope>provided</scope>
            </dependency>

    注意这里scope要设置provided,表明只在编译和测试的时候用,这样启动tomcat的时候就不会冲突了。
    总结一下Springboot使用外部tomcat同时又有websocket前后端通信时,解决方案步骤:
    1:移除config配置bean

    2:pom里通过maven管理添加javax.websocket 的相关JAR包

            <dependency>
                <groupId>javax.websocket</groupId>
                <artifactId>javax.websocket-api</artifactId>
                <version>1.1</version>
                <scope>provided</scope>
            </dependency>

    3:WebSocketController里@Component注解不用动,网上有说发布到服务器需要删除该标签才能够通过ws请求到接口的,本人亲测如果不加@Component标签,才会请求不到ws的路径接口。所以该标签必须加。

    至此,打包后上传到服务器就可以通过websocket通信啦。

    两个小坑:
    一:
    WebSocketController里无法@Autowired自动注入bean一直为空的问题,其原因在一个大佬的博客里找到了。

    奉上:
    由于于Spring本质上管理的都是单例(singleton),和 websocket (多对象)相冲突。
    详细解释:项目启动时初始化,会初始化 websocket (非用户连接的),spring 同时会为其注入 service,该对象的 service 不是 null,被成功注入。但是,由于 spring 默认管理的是单例,所以只会注入一次 service。当新用户进入聊天时,系统又会创建一个新的 websocket 对象,这时矛盾出现了:spring 管理的都是单例,不会给第二个 websocket 对象注入 service,所以导致只要是用户连接创建的 websocket 对象,都不能再注入了。

    像 controller 里面有 service, service 里面有 dao。因为 controller,service ,dao 都有是单例,所以注入时不会报 null。但是 websocket 不是单例,所以使用spring注入一次后,后面的对象就不会再注入了,会报null。

    解决方法:将要注入的 service 改成 static,就不会为null了。

    @Controller
    @ServerEndpoint(value="/chatSocket")
    public class ChatSocket {
        //  这里使用静态,让 service 属于类
        private static ChatService chatService;
    
        // 注入的时候,给类的 service 注入
        @Autowired
        public void setChatService(ChatService chatService) {
            ChatSocket.chatService = chatService;
        }
    }

    版权声明:本文为CSDN博主「亦寒2017」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/m0_37202351/article/details/86255132



  • 相关阅读:
    VS2005 web程序自定义安装包的制作[转]
    "控件必须放在具有 runat=server 的窗体标记内"错误的解决方法
    Reader转化为Entity类时系统性能的测试报告
    NetBeans6.1(6.5)Visual Web JSF 应用程序开发的一个BUG
    .net操作PDF的一些资源(downmoon收集)
    NetBeans中jsp或java乱码的几种办法(downmoon收集)
    后微软时代,我们还能依靠谁?(downmoon原创)
    从dataReader到Entity转化时利用Reflect示例(解决OutOfRangeException错误)(downmoon)
    HttpCookie.HttpOnly VS Cookie.HttpOnly?(downmoon原创)
    Windows PowerShell 编写正则表达式(转自TechNet Magazine)
  • 原文地址:https://www.cnblogs.com/nongzihong/p/12937711.html
Copyright © 2011-2022 走看看