Dev*_*evy 4 python proxy curl nginx websocket
在过去的几天里,我一直试图让 Nginx WebSocket 代理工作,但在我的一生中,我无法让它工作。我按照官方指南here,一直使用 Python 的websockets
模块作为服务器,使用 npm 包wscat
作为客户端。wscat
与 Python WebSocket 后端的直接连接工作正常(来自浏览器的连接也是如此)。但是一旦我在 Nginx 中分层,它就无法正常工作并继续给我一个标准的 HTTP 301 重定向。
使用 Nginx 代理的 cURL 调试输出:
$ curl 'http://test.ws:8080/websocket' \
> -H 'Pragma: no-cache' \
> -H 'Origin: http://localhost:8080' \
> -H 'Accept-Encoding: gzip, deflate, sdch' \
> -H 'Sec-WebSocket-Version: 13' \
> -H 'Sec-WebSocket-Key: V15bszpaQ+8Vq7mWR6NQbQ==' \
> -H 'User-Agent: Mozilla/5.0' \
> -H 'Upgrade: websocket' \
> -H 'Cache-Control: no-cache' \
> -H 'Connection: Upgrade' \
> -H 'Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits' \
--compressed -v
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to test.ws (127.0.0.1) port 8080 (#0)
> GET /websocket HTTP/1.1
> Host: test.ws:8080
> Accept: */*
> Pragma: no-cache
> Origin: http://localhost:8080
> Accept-Encoding: gzip, deflate, sdch
> Sec-WebSocket-Version: 13
> Sec-WebSocket-Key: V15bszpaQ+8Vq7mWR6NQbQ==
> User-Agent: Mozilla/5.0
> Upgrade: websocket
> Cache-Control: no-cache
> Connection: Upgrade
> Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
>
< HTTP/1.1 301 Moved Permanently
* Server nginx/1.8.0 is not blacklisted
< Server: nginx/1.8.0
< Date: Mon, 10 Aug 2015 15:04:26 GMT
< Content-Type: text/html
< Content-Length: 184
< Location: http://test.ws:8080/websocket/
< Connection: keep-alive
<
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
* Connection #0 to host test.ws left intact
Run Code Online (Sandbox Code Playgroud)
没有Nginx 代理的cURL 调试输出:
$ curl 'http://test.ws:8765/' \
> -H 'Pragma: no-cache' \
> -H 'Origin: http://localhost:8080' \
> -H 'Accept-Encoding: gzip, deflate, sdch' \
> -H 'Sec-WebSocket-Version: 13' \
> -H 'Sec-WebSocket-Key: V15bszpaQ+8Vq7mWR6NQbQ==' \
> -H 'User-Agent: Mozilla/5.0' \
> -H 'Upgrade: websocket' \
> -H 'Cache-Control: no-cache' \
> -H 'Connection: Upgrade' \
> -H 'Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits' \
> --compressed -v
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to test.ws (127.0.0.1) port 8765 (#0)
> GET / HTTP/1.1
> Host: test.ws:8765
> Accept: */*
> Pragma: no-cache
> Origin: http://localhost:8080
> Accept-Encoding: gzip, deflate, sdch
> Sec-WebSocket-Version: 13
> Sec-WebSocket-Key: V15bszpaQ+8Vq7mWR6NQbQ==
> User-Agent: Mozilla/5.0
> Upgrade: websocket
> Cache-Control: no-cache
> Connection: Upgrade
> Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
>
< HTTP/1.1 101 Switching Protocols
* Server Python/3.4 websockets/2.5 is not blacklisted
< Server: Python/3.4 websockets/2.5
< Upgrade: WebSocket
< Connection: Upgrade
< Sec-WebSocket-Accept: yR97tmHAm9KPEI5vfKiM0/sfTqQ=
^C
Run Code Online (Sandbox Code Playgroud)
我的 Nginx(版本1.8.0
)配置是这样的(websockets 在 test.ws (127.0.0.1) 的 8765 端口上运行),而 nginx 正在 localhost 上的 8080 端口上监听:
worker_processes 1;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream ws {
server 127.0.0.1:8765;
}
# map $http_upgrade $connection_upgrade {
# default upgrade;
# '' close;
# }
server {
listen 8080;
server_name test.ws;
access_log logs/localhost.access.log;
location / {
root html;
index index.html index.htm;
}
location /websocket/ {
proxy_pass http://ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
include servers/*;
Run Code Online (Sandbox Code Playgroud)
任何人都知道我在这里做错了什么,为什么它给了我 301 重定向?
事实证明,我的 Nginx 配置中的根位置节一直在干扰 WebSocket 代理传递隧道。有三种方法可以解决这个问题。
修改根位置节以完全匹配。
location = / {
root html;
index index.html index.htm;
}
Run Code Online (Sandbox Code Playgroud)将根位置节重新排序为位置节之后websocket
(首先是特定的,最后是一般的,就像重写匹配规则的工作方式一样)。
删除 Nginx 配置中的以下根位置节将使其正常工作。
location / {
root html;
index index.html index.htm;
}
Run Code Online (Sandbox Code Playgroud) 归档时间: |
|
查看次数: |
8164 次 |
最近记录: |