最近在用go語言的leaf框架開發H5遊戲的服務器端,用websocket的方式進行服務器與客戶端之間的通訊。然後之前都是本地websocket開發,要部署到facebook平臺的時候,平臺要求與第三方服務器通訊需要有ssl證書。微信小程序同理。
所以決定用nginx進行反向代理,將websockets(wss)請求轉發到原來服務器的websocket請求。這樣可以不用修改服務器端的代碼,同時後續也可以配置負載均衡的功能。
由於公司服務器還沒有申請下來,ssl證書也還沒申請下來,於是決定先在本地完整試驗一下整個流程。
PS:本教程步驟與具體服務器語言無關
首先先在本地搭建一個測試環境:
1、下載nginx
下載地址:http://nginx.org/en/download.html (建議下載穩定版的)
下載之後解壓到某個文件夾,然後shift+右鍵——在此處打開控制檯,輸入start nginx啓動服務器
在瀏覽器輸入localhost,如果有出來nginx頁面就代表成功了。
具體命令行操作可以參考這篇博客:https://www.cnblogs.com/saysmy/p/6609796.html
2、在本地生成免費的ssl證書。(如果自己公司或者自己網站有認證證書可以跳過此步)
免費SSL生成工具:http://slproweb.com/products/Win32OpenSSL.html
進去了之後下載最新的安裝包安裝即可,當前最新版本是 Win64 OpenSSL v1.1.0i
如果網站掛了也可以從國內的資源站下載:https://oomake.com/download/openssl
然後參考這篇博客生成屬於自己的ssl證書:https://blog.csdn.net/kwy15732621629/article/details/76602241
3、找到nginx配置文件
打開Nginx安裝目錄,找到 conf/nginx.conf 配置文件。
這個配置文件每一行代表什麼意思可以參考這篇博客 https://www.cnblogs.com/Miss-mickey/p/6734831.html
這篇博客也講了http的反向代理,有空可以試試,沒空就不用細看了。
注意,“#” 開頭的一行表示配置文件的註釋,不要寫着寫着寫混了寫到被註釋掉的配置信息裏了。
4、修改配置文件,進行websocket反向代理
在配置文件中的 http{ } (http大括號裏面)中加上如下代碼
# 實際websocket服務器地址
upstream wss_svr {
server 192.168.213.182:3653 weight=1;
}
# 443 ssl端口配置,實際websockets(wss)地址
server {
listen 443;
server_name 192.168.213.182;
ssl on;
# 自己的證書,放在與nginx.conf同一文件夾下。(若放不同文件夾註意路徑問題)
ssl_certificate dhxtest.crt;
ssl_certificate_key dhxtest_nopass.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2 SSLv3;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
ssl_verify_client off;
location / {
proxy_redirect off;
proxy_pass http://wss_svr; # 轉發
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # 升級協議頭
proxy_set_header Connection upgrade;
}
}
其中,我原來的遊戲服務器是192.168.213.182:3653,而外部需要訪問的地址是 192.168.213.182:443
location的proxy_pass就將wss請求轉發到http://wss_svr; 也就是我原來的websocket地址 http://192.168.213.182:3653;
最後兩行的set_header表示將http協議頭升級爲websocket協議
最後結果:訪問 wss://192.168.213.182:443,nginx轉發請求到 ws://192.168.213.182:3653,然後和3653端口的websocket服務進行通信
自此,Nginx反向代理完成。
5、測試配置成果
通用測試方法:
1)首先打開nginx —— 控制檯輸入start nginx
2)打開你原來的服務器,我的服務器是go遊戲服務器,服務端口是我本機的3653端口。
3)打開chrome瀏覽器,打開任意頁面,按F12 - console打開瀏覽器控制檯,在控制檯輸入
var wss = new WebSocket("wss://192.168.213.182:443")
如果不報錯,提示undefined,就是成功連接啦。如果你原來的服務器有連接提示,此時應該也能夠看到有人連接到了你的websocket端口。
PS:此連接方法是在沒有客戶端的情況下測試,如果有對應客戶端按原來的流程看是否正常代理了請求即可
6、可能報錯
報錯1:chrome瀏覽器提示 WebSocket connection to 'wss://192.168.213.182/' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT ,代表根本沒連接上你原來的服務器。檢查一下端口是否都寫對了,配置是否按上面的流程走下來了
報錯2:chrome瀏覽器提示 NET::ERR_CERT_COMMON_NAME_INVALID ,這個是由於你的chrome瀏覽器識別出目標443地址的證書是自己頒發的,給你禁止了。解決辦法:直接輸https://你的域名,點高級-繼續前往你的域名。後續即可成功連接了。
報錯3:此條針對go leaf遊戲服務器框架。leaf框架的websocket部分是使用到了gorilla/websocket庫,連接後,gorilla/websocket報錯websocket: the client is not using the websocket protocol: 。搜索這條報錯的提示的地方,然後調試進gorilla/websocket庫裏那條報錯前後對應代碼,會發現header中connection部分的值爲" "upgrade" ",多了一對引號,導致http協議升級ws失敗。這個的原因是因爲在配置文件中最後一行寫成了proxy_set_header Connection "upgrade"; 很多教程都會在最後upgrade這邊多一個引號,但是對於golang的gorilla/websocket庫,以這種反向代理升級的方式,引號也會被引用進去,所以會報錯。解決辦法就是刪除引號即可。