【问题标题】:The handshake response is empty in the flask-socketio wssflask-socketio wss 中的握手响应为空
【发布时间】:2019-08-21 12:55:41
【问题描述】:

我通过在nginx中应用ssl来做wss并且连接成功但是响应消息是空的,我想解决它。 ws 工作正常。

我的开发环境 => windows os + nginx(ssl) + flask(gevent.pywsgi) + flask-socketio

我尝试使用 socketio.run(...) 而不使用 gevent.pywsgi。

这是我的python代码

from flask import Flask
from flask_socketio import SocketIO
from datetime import datetime

app = Flask(__name__)
app.secret_key = b'...'
api = Api(app)
socketio = SocketIO(app, async_mode='gevent')


@socketio.on('connect', namespace='/test')
def ws_connect_handler():
    print('[{}] WSS : Connect'.format(
        datetime.today().strftime("%Y.%m.%d %H:%M:%S")
    ))


if __name__ == '__main__':
    from gevent.pywsgi import WSGIServer
    from geventwebsocket.handler import WebSocketHandler

    http_server = WSGIServer(('127.0.0.1', 5000), app,
                             handler_class=WebSocketHandler)
    http_server.serve_forever()

这是我的 nginx.conf

upstream site {
    ip_hash;

    server 127.0.0.1:5000;
}

server {
    listen 80;
    server_name test.com;
    return 301 https://$host$request_uri;
}

server {
    listen      443 ssl;
    server_name test.com;

    ssl_certificate      test.com.crt;
    ssl_certificate_key  test.com.key;

    ssl_session_timeout 5m;

    ssl_protocols SSLv3 TLSv1 ;
    ssl_ciphers ALL:!ADH:!EXPORT56:!RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
    ssl_prefer_server_ciphers on;

    location /socket.io {
        proxy_pass http://site/socket.io;
        proxy_redirect off;
        proxy_buffering off;

        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

    location / {
        proxy_pass http://site;
        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

}

这是我的客户端代码(javascript)

namespace = '/test'
sock = io.connect(namespace, {
    transports: ['websocket'],
    upgrade: false,
    secure: true
}, { forceNew: true });

sock.on('connect', function () {
    console.log('connect')
})

Chrome 浏览器开发者模式的 Networks 标签中显示的 wss 响应头和消息。

wss 响应头

Request URL: wss://127.0.0.1/socket.io/?EIO=3&transport=websocket
Request Method: GET
Status Code: 101 Switching Protocols

Connection: upgrade
Date: Wed, 21 Aug 2019 00:20:39 GMT
Sec-WebSocket-Accept: /m8mof9UqVSVTXwmPv1dSyi/JLM=
Server: nginx/1.16.0
Upgrade: websocket
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: Upgrade
Host: 127.0.0.1
Origin: https://127.0.0.1
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: uRnBf+4zGudyfFa+D18FdQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36

EIO: 3
transport: websocket

但消息中没有收到任何内容。

如果正常,消息 0{"sid": "...", "upgrades": [], "pingTimeout": 60000, "pingInterval": 25000} 应该会到达。

【问题讨论】:

    标签: python ssl nginx websocket flask-socketio


    【解决方案1】:

    我解决了。

    在创建 flask-socketio 时,将 cors_allowed_origins 参数设置为 '*'。

    socketio = SocketIO(app, async_mode='gevent', cors_allowed_origins='*')
    

    这是一个 Websockets CORS 政策问题。

    【讨论】:

    • 允许所有来源是有风险的,它会使您面临潜在的 CSRF 攻击。我建议您列出您希望在应用程序中支持的特定来源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 2016-05-04
    • 2016-05-17
    • 2015-03-27
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    相关资源
    最近更新 更多