Springboot使用外置tomcat的同时使用websocket通信遇到的坑 - Go语言中文社区

Springboot使用外置tomcat的同时使用websocket通信遇到的坑


Springboot集成websocket进行前后端你通信
上一章讲到Springboot集成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。

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

解决方法:

    //设置controller为静态
    private static ContestController contestController;
    //为静态对象注入
    @Autowired
    public void setContestController(ContestController contestController){
        WebSocketController.contestController = contestController;
    }

最少的代码解决问题

二:websocket在本地测试都没问题,部署到服务器本机还是可以进行websocket通信,其他机器访问服务器ip时候不能通信,原因在于js端建立通信的地址

var url = "ws://localhost:8080/hznuctf/websocket/"+loginUser.userId+"/"+competitionId+"/"+loginUser.teamId;

使用localhost建立通信当然不行啦,小错误,应该改成服务器的ip地址,这样就能进行正常通信了。因为服务器不管是ip还是localhost都是本机,而其他机器不行。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_43323720/article/details/99660430
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢