前景回顧
最近自己的服務(wù)器需要上上線一個(gè)websocket服務(wù)诱担,本地測(cè)試什么的都是正常的,知道上線的時(shí)候,發(fā)現(xiàn)報(bào)了如下錯(cuò)誤
從圖中可以發(fā)現(xiàn)毅弧,如果內(nèi)嵌websocket的站點(diǎn)是https加密的,則需要使用wss協(xié)議当窗,而不是ws協(xié)議够坐。毫無(wú)疑問(wèn)我們就需要使用 wss:\ 安全協(xié)議了,那不簡(jiǎn)單,直接把ws:\ 改為 wss:\ 不就行了元咙?
說(shuō)干就干梯影。
好吧,還是太天真
上面的錯(cuò)誤很明顯 SSL 協(xié)議錯(cuò)誤庶香,說(shuō)明就是證書(shū)問(wèn)題了光酣。測(cè)試的時(shí)候我們一直拿的是 IP地址 + 端口號(hào) 這種方式連接 WebSocket 的,所以一直不存在問(wèn)題脉课,但是生成環(huán)境我們肯定不能再用 IP地址 + 端口號(hào)這種形式了救军。看來(lái)簡(jiǎn)單的改協(xié)議頭解決不了問(wèn)題倘零。那么怎么才能解決問(wèn)題呢唱遭?
方法一:Nginx 配置域名支持 WSS
#在nginx內(nèi)添加該段內(nèi)容
location /websocket {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
上文的具體作用就是將原來(lái)的websocket端口,掛載在https對(duì)應(yīng)服務(wù)器下的/websocket路由下呈驶,http://backend 就是你的websocket url 拷泽。這樣就完成了,在 HTTPPS 下以域名方式連接 WebSocket袖瞻。
稍微解釋一下 Nginx 配置
Nginx 自從 1.3 版本就開(kāi)始支持 WebSocket 了司致,并且可以為 WebSocket 應(yīng)用程序做反向代理和負(fù)載均衡。
WebSocket 和 HTTP 協(xié)議不同聋迎,但是 WebSocket 中的握手和 HTTP 中的握手兼容脂矫,它使用 HTTP 中的 Upgrade 協(xié)議頭將連接從 HTTP 升級(jí)到 WebSocket,當(dāng)客戶端發(fā)過(guò)來(lái)一個(gè) Connection: Upgrade
請(qǐng)求頭時(shí)霉晕,Nginx 是不知道的庭再,所以,當(dāng) Nginx 代理服務(wù)器攔截到一個(gè)客戶端發(fā)來(lái)的 Upgrade
請(qǐng)求時(shí)牺堰,需要顯式來(lái)設(shè)置Connection
拄轻、Upgrade
頭信息,并使用 101(交換協(xié)議)返回響應(yīng)伟葫,在客戶端和代理服務(wù)器恨搓、后端服務(wù)器之間建立隧道來(lái)支持 WebSocket。
當(dāng)然筏养,還需要注意一下斧抱,WebSockets 仍然受到 Nginx 缺省為60秒的 proxy_read_timeout 的影響。這意味著撼玄,如果你有一個(gè)程序使用了 WebSockets夺姑,但又可能超過(guò)60秒不發(fā)送任何數(shù)據(jù)的話墩邀,那你要么需要增加超時(shí)時(shí)間掌猛,要么實(shí)現(xiàn)一個(gè) ping 的消息以保持聯(lián)系。使用 ping 的解決方法有額外的好處,可以發(fā)現(xiàn)連接是否被意外關(guān)閉荔茬。
更具體文檔詳見(jiàn) Nginx 官方文檔:http://nginx.org/en/docs/http/websocket.html
方法二:
這個(gè)方法就比較復(fù)雜了废膘,需要在你的websocket服務(wù)器下加入證書(shū)支持。