如果使用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