Nginx配置Websocket
WebSocket 和HTTP雖然是不同協(xié)議,但是兩者“握手”方式兼容。通過HTTP升級(jí)機(jī)制,使用HTTP的Upgrade和Connection協(xié)議頭的方式可以將連接從HTTP升級(jí)為WebSocket。
Websocket 使用 ws 或 wss 的統(tǒng)一資源標(biāo)志符,類似于 HTTPS,其中 wss 表示在 TLS 之上的 Websocket。如:
ws://example.com/wsapi
wss://secure.example.com/
Websocket 使用和 HTTP 相同的 TCP 端口,可以繞過大多數(shù)防火墻的限制。默認(rèn)情況下,Websocket 協(xié)議使用 80 端口;運(yùn)行在 TLS 之上時(shí),默認(rèn)使用 443 端口。
一個(gè)典型的Websocket握手請(qǐng)求如下:
客戶端請(qǐng)求:
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13
服務(wù)器回應(yīng):
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/
關(guān)鍵點(diǎn):
- Connection 必須設(shè)置 Upgrade,表示客戶端希望連接升級(jí)。
- Upgrade 字段必須設(shè)置 Websocket,表示希望升級(jí)到 Websocket 協(xié)議。
知識(shí)點(diǎn)參考:《HTML5 WebSocket》
一、對(duì)wss與nginx代理wss的理解:
1、wss協(xié)議實(shí)際是websocket +SSL,就是在websocket協(xié)議上加入SSL層,類似https(http+SSL)。
2、利用nginx代理wss【通訊原理及流程】
- 客戶端發(fā)起wss連接連到nginx
- nginx將wss協(xié)議的數(shù)據(jù)轉(zhuǎn)換成ws協(xié)議數(shù)據(jù)并轉(zhuǎn)發(fā)到Workerman的websocket協(xié)議端口
- Workerman收到數(shù)據(jù)后做業(yè)務(wù)邏輯處理
- Workerman給客戶端發(fā)送消息時(shí),則是相反的過程,數(shù)據(jù)經(jīng)過nginx/轉(zhuǎn)換成wss協(xié)議然后發(fā)給客戶端
二、Nginx配置Websocket參數(shù)
示例一:某站點(diǎn)或域名下面代理配置
server {
listen 80;
server_name 域名;
proxy_http_version 1.1;
……
#啟用支持websocket連接的配置
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
location / {
proxy_redirect off;
proxy_pass http://myweb_backend;
proxy_connect_timeout 60;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
}
重要的是這兩行,它表明是websocket連接進(jìn)入的時(shí)候,進(jìn)行一個(gè)連接升級(jí)將http連接變成websocket的連接。
啟用支持websocket連接:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy read timeout 表明連接成功以后等待服務(wù)器響應(yīng)的時(shí)候,如果不配置默認(rèn)為60s;
proxy_http_version 1.1;表明使用http版本為1.1
示例二:全部站點(diǎn)或全部服務(wù)的代理配置
上面的配置將websocket寫到某個(gè)server里了。實(shí)際項(xiàng)目上nginx代理的可能是多個(gè)站點(diǎn),多個(gè)服務(wù),這就需要統(tǒng)一設(shè)置一下。另外對(duì)于低版本nginx的配置不支持"upgrade"參數(shù)的情況下可以這樣寫:
首先在nginx的全局塊(一般是http塊)里面加上websocket的參數(shù)映射
http {
include mime.types;
default_type text/html;
charset utf-8;
log_format proxy '$http_x_real_ip - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $request_time $upstream_response_time';
access_log /dev/stdout proxy;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 75;
keepalive_requests 1000;
client_max_body_size 1020000M;
client_body_buffer_size 256k;
large_client_header_buffers 4 128k;
client_header_buffer_size 32k;
server_names_hash_max_size 512;
server_names_hash_bucket_size 128;
#注意,必須加下面這段websocket的參數(shù)映射
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include /etc/nginx/conf.d/*.conf;
}
這里重要的是這四行:
注意,必須加下面這段websocket的參數(shù)映射
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
然后在你的server或者location塊里面加上這兩行即可:
server {
listen 80;
server_name 域名;
proxy_http_version 1.1;
……
#注意,必須加下面這段websocket的配置
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
location / {
proxy_redirect off;
proxy_pass http://myweb_backend;
proxy_connect_timeout 60;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
}
- 示例一和示例二配置一種就行。
狀態(tài)碼說明
注意:因?yàn)閣ebsocket是長連接,請(qǐng)求過程不關(guān)閉的所以一般連接狀態(tài)碼是101(請(qǐng)求者已要求服務(wù)器切換協(xié)議,服務(wù)器已確認(rèn)并準(zhǔn)備切換。)
CloseEvent接口的代碼只讀屬性返回WebSocket連接關(guān)閉代碼,指示服務(wù)器關(guān)閉連接的原因。
值:一個(gè)整數(shù)的WebSocket連接關(guān)閉范圍為1000-4999的代碼,指示服務(wù)器關(guān)閉連接的原因。
websocket連接關(guān)閉狀態(tài)碼:
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
不支持websocket協(xié)議現(xiàn)象說明
網(wǎng)頁控制臺(tái)報(bào)錯(cuò)現(xiàn)象:
1)現(xiàn)象一:網(wǎng)頁控制臺(tái)報(bào)"WebSocket connection to 'ws://' failed:<無報(bào)錯(cuò)信息>"
2)現(xiàn)象二:網(wǎng)頁控制臺(tái)報(bào)"WebSocket connection to 'ws://' failed:Error during WebSocket handshake: Unexpected response code: 400"
3)現(xiàn)象三:網(wǎng)頁控制臺(tái)報(bào)"WebSocket connection to 'ws://' failed:The request timed out.
問題原因與處理方法:
1.代理/防火墻對(duì)訪問端口只開通了http協(xié)議,未支持websocket協(xié)議。可以將代理/防火墻的7層轉(zhuǎn)發(fā)改為4層轉(zhuǎn)發(fā),確認(rèn)是否為websocket協(xié)議/長連接的支持問題。
2.代理nginx未支持websocket協(xié)議轉(zhuǎn)發(fā),檢查nginx配置文件中的Upgrade和Connection配置。
【完】
總結(jié)
以上是生活随笔為你收集整理的Nginx配置Websocket的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenJDK 从 Mercurial
- 下一篇: AMD计算和图形业务Q2营收13.7亿美