Websocket 環境架設 (以 Node JS 為 server)
我一直是利用 Django 的框架架網站,且有跑其它應用程式的需求,所以一般環境都會建置在 Windows 的平台下。由於 Django 有提供 channel 模組來建立 Websocket 的應用,之前也有成功的搭配 apache 讓 websocket 跑起來,但只能在 Django 自帶的 server 下跑 websocket,一旦正式上線,總有一些搭配的元件問題無法解決。最近我重新整理網站,又再度碰到這個問題,不過這次我直接捨棄效能不彰的而又處處受限的 apache,改採 nginx 作為 web server,經過幾天的摸索,終於把 Websocket 跑起來,讓它可以在 SSL 加密連線的狀態下執行。以下就是本次架設網站的紀錄,作為往後的參考。
目前的環境是:
Windows 10 + NodeJS V18.12.1 + Python 3.6 + Django 2.0 + Nginx 1.22.0
(SSL 的申請是透過 Certbot 這個工具來申請 SSL,詳見之前文章的描述 https://blog1.jinvent.com.tw/network/)
由於是搭建在現有的網頁上,如果原本的網頁執行沒有問題,那主要的環境問題就只剩下 NodeJS 跟 Nginx 的設定了。首先先看 Nginx 的設定,裡面關於 websocket 的部分,這裡主要是參考 https://www.nginx.com/blog/websocket-nginx/ 及 https://www.51cto.com/article/704378.html 瞭篇文章中的說明。下面是節錄我部份 nginx.conf 的內容:
upstream websocket {
server 127.0.0.1:xxxx;
server 127.0.0.1:xxxx;
keepalive 1000;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
#listen 443 ssl;
return 301 https://blog1.jinvent.com.tw$request_uri;
server_name blog1.jinvent.com.tw;
root <path>/;
ssl_certificate <path>fullchain.pem;
ssl_certificate_key <path>privkey.pem;
ssl_session_timeout 5m;
charset utf-8;
location / {
proxy_pass http://websocket;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /static {
alias <static path>
}
}
如果在加入 websocket 機制之前的網站都可以執行,那麼加入 websocket 後,其中主要需注意的就是藍字部分。而 upstream websocket 裡的 127.0.0.1:xxxx; 其實就是從 proxy_pass http://127.0.0.1:xxxx; 搬過去的。這個環節曾困擾我一兩天,所幸最後解決了,接下來關於 NodeJS 部分,待過幾天再來分享。