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