spring cloud整合 websocket 的那些事


我們知道, 現在很多瀏覽器都已經是直接支持 websocket 協議的了,  除此之外, sockjs, 也可以實現 websocket 功能.. 當然, 其原理是不同的.

一開始 websocket 已經做好了,  但是后面發現 websocket不能穿透zuul ,

 

出現

com.netflix.zuul.exception.ZuulException: Forwarding error ... 等問題.

找到了 https://blog.csdn.net/moshowgame/article/details/80511158

修改了ZuulFilter , 貌似行了, 結果仍然各種問題.. 

 

真是郁悶了.  網上的關於springboot + websocket 資料很多

https://blog.csdn.net/qq_39320953/article/details/77852126 基本可用

https://blog.csdn.net/jie873440996/article/details/70257558 非常詳細

https://blog.csdn.net/haoyuyang/article/details/53364372 很好

https://segmentfault.com/a/1190000006617344 stomp介紹

https://blog.csdn.net/nongshuqiner/article/details/78792079 sockjs介紹

 

好像stomp能解決問題....  哦, 改stomp吧, 但很快遇到問題:

org.springframework.web.socket.sockjs.SockJsMessageDeliveryException: Failed to ..

原來js 也是需要改的..

參考 https://my.oschina.net/robinjiang/blog/898557

 

, 但是 zuul + websocket 的資料就少了. 

 

其實也是找到了幾個的, 但是呢, 不能完全拿過來用, 因為1 沒有它們的源代碼, 2 認證機制不一樣..  怎么辦呢? 升級到 zuul2 ? 使用 spring-cloud-gateway? spring-cloud-gateway 下載了一個示例, 基本是可行的.  但是, 這樣的話, 需要整個升級, 改動也太大了..

 

終於找到了 一篇: https://github.com/mthizo247/spring-cloud-netflix-zuul-websocket 

示例也親測可用, 但是, 拿過來到我們項目就不行了,  出現各種問題, 

 

首先是   認證機制不一樣.. 我們登錄都是基於token 的, mthizo247是基於spring security的, 發送點對點消息遇到各種問題:

annotation.support.MissingSessionUserException: No "user" header in message:

找到答案: 

You are trying to subscribe to a user destination so the user must be authenticated.

If that is an anonymous user who want to subscribe to the topic, answer to this questionwill help.

You'll have to assign an anonymous identify to the user and there are two options:

  1. Configure a sub-class of DefaultHandshakeHandler that overrides determineUserand assigns some kind of identity to every WebSocketSession.

  2. The WebSocket session will fall back on the value returned from HttpServletRequest.getUserPrincipal on the handshake HTTP request. You could have a servlet Filter wrap the HttpServletRequest and decide what to return from that method. Or if you're using Spring Security which has the AnonymousAuthenticationFilter, override its createAuthentication method.

https://stackoverflow.com/questions/36616167/spring-websocket-missingsessionuserexception-no-user-header-in-message

http://www.itkeyword.com/doc/0662498046730811x767/spring-websocket-missingsessionuserexception-no-user-header-in-message

https://stackoverflow.com/questions/36847814/spring-websocket-send-message-from-a-queue-to-a-user-convertandsendtouser-not-wo

 

這個通過 stomp 建立連接時候 設置 nativeHeaders 解決了, nativeHeaders  也是很難獲取到的, 后面 通過stomp 發出的event , 終於是解決了.

另外, mthizo247 群發消息會出現 重復消息的情況, 這就尷尬了..  這個問題比較難比較, 我仔細調試過mthizo247的源碼, 發現里面session 的數量剛好出現了重復, 這樣就導致了 前端接收到重復消息,,, 怎么辦呢 ? 

我后面想出了一個折中的解決方案: 

https://github.com/mthizo247/spring-cloud-netflix-zuul-websocket/issues/4 

 


問題好像解決了, 但是, convertAndSendToUser 好像不工作了??

 simpMessagingTemplate convertAndSendToUser

哦, 仔細一看是代碼bug, mthizo247  也需要配合修改.. 

 

問題好像解決了, 但是, 又,

Failed to send message to ExecutorSubscribableChannel[clientInboundChannel

...

NoClassDefFoundErrorc org/springframework/integration/channel/DirectChannel

...

 

分析了下, 好像是sleuth 出來搗亂, dependency 中先屏蔽它吧, 然后呢, 有發現一個NosuchMethodError 之類的錯誤, 仔細分析, 發現是 spring-message的版本不一致, 當然, 這個是由於spring-boot 版本不一致導致的...  改吧..

 

但是,  我們前后端是分離的, 前端除了瀏覽器, 還有nodejs 服務器呢..  瀏覽器刷新之后, stomp 連接就斷開了, 但是 nodejs 服務器 和zuul 的連接確實沒有斷開的..

sockjs.js:3559 'protocols_whitelist' is DEPRECATED. Use 'transports' instead.

Opening Web Socket...
Web Socket Opened...


>>> CONNECT
token:u1
accept-version:1.1,1.0
heart-beat:10000,10000

<<< CONNECTED
version:1.1
heart-beat:0,0
user-name:u1

connected to server undefined

>>> SUBSCRIBE
id:sub-0
destination:/user/queue/notifications



瀏覽器刷新出現:

>>> CONNECT
token:u1
accept-version:1.1,1.0
heart-beat:10000,10000

Whoops! Lost connection to http://10.10.10.76:9999/lk-websocket

 

因為nodejs 服務器的存在, 瀏覽器刷新 會進行重連,  然后導致重新建立連接, 但是, 當前用戶的連接以及存在了, 所以就無法再建立了, 所以就  Lost connection ...   怎么辦呢?  nodejs  端處理吧...    當連接斷開的時候, nodejs 服務器檢測到了, 然后也同樣的像zuul 主動發起一個連接斷開的請求.. 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM