SpringBoot- 技術專題 -Websocket+Nginx出現404問題

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"問題描述:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 使用websocket往商家管理系統發送消息。在本地測試沒有任何問題,但是部署到centos服務器上之後一直報錯404。總結了網上很多解決方法都不行,網上討論的都是說tomcat版本太低,因爲websocket需要tomcat7.0以上才支持。"}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"解決思路:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 排除了tomcat問題,jdk版本也是1.8+,websocket部署到服務器上還是404,網上還有人說是tomcat的jar包和項目jar衝突,可是我springboot項目使用的內嵌tomcat,於是我利用Maven Helper(非常好用的idea插件)查看了下依賴發現並沒有衝突。卡在這裏很久,我特地看了下websocket請求格式:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Websocket握手格式:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"GET /chat HTTP/1.1\nHost: server.example.com\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\nSec-WebSocket-Protocol: chat, superchat\nSec-WebSocket-Version: 13\nOrigin: http://example.com12345678"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這請求類似http協議,裏面多了陌生的內容是:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"Upgrade: websocket\nConnection: Upgrade12"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 當時一臉懵逼,這是什麼玩意啊?然後我就百度了下,原來這個就是Websocket的核心,他會告訴Apache、Nginx等服務器我發起的是websocket請求,不是http!下面的三個參數Sec-WebSocket-Key、Sec-WebSocket-Protocol、Sec-WebSocket-Version作用大概就是驗證請求確實是websocket,同時指定協議版本吧。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 這時候我恍然大悟!我的項目使用了nginx做了轉發,那麼會不會是因爲我沒有配置nginx響應websocket請求呢?答案是肯定的!"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"配置nginx反向代理響應webSocket請求"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要在代理的請求配置中加入下面的配置:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"proxy_set_header Upgrade $http_upgrade;\nproxy_set_header Connection \"upgrade\";12"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"nginx配置如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"server {\n listen 80;\n server_name localhost;\n #charset koi8-r;\n\n location / {\n root /usr/java/myproject/sell;\n index index.html index.htm;\n }\n\n location /sell/ {\n proxy_pass http://127.0.0.1:8081/sell/;\n }\n\nlocation /sell/webSocket {\n proxy_pass http://127.0.0.1:8081/sell/webSocket; \n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n}12345678910111213141516171819"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這段配置就是把所有的/sell下的請求轉到8081端口處理,把/sell/webSocket請求轉發到指定的請求接口,發現404錯誤消失,webSocket服務也可以訪問到。但是出現了一個新的問題就是,webSocket連接後沒有保持連接,大約一分鐘之後就會斷開,原因是因爲在第一次請求後到第二次請求到來的時間超過了默認的最大時間,超時了。這裏提供一個解決思路:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要配置的三個核心參數:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"proxy_connect_timeout 4s; \nproxy_read_timeout 7200s; \nproxy_send_timeout 12s; 123"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"proxy_read_timeout是服務器對連接等待的最大時間,也就是說,當你webSocket使用nginx轉發的時候,用上面的配置來說,如果72000秒內沒有通訊,依然是會斷開的,你可以按照需求來設定。"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如說,我這裏設置了7200s(2小時),那麼如果我2小時內有通訊,或者2小時內有心跳的話,是可以保持連接不中斷的。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我這裏之所以這麼設置,是考慮到了具體的業務情況,2小時比較合適。最終的配置如下:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"server {\n listen 80;\n server_name localhost;\n #charset koi8-r;\n\n location / {\n root /usr/java/myproject/sell;\n index index.html index.htm;\n }\n\n location /sell/ {\n proxy_pass http://127.0.0.1:8081/sell/;\n }\n\nlocation /sell/webSocket {\n proxy_pass http://127.0.0.1:8081/sell/webSocket; \n proxy_connect_timeout 4s; \n proxy_read_timeout 7200s; \n proxy_send_timeout 12s; \n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章