heroku - Flask-socketio 的 https、http、wss 问题无法在 Heroku 中连接
问题描述
我有一个几个月前可以工作的烧瓶套接字 io 应用程序,但我不确定发生了什么。我已将其简化为基础知识。输出日志显示了一堆乱码,我认为这应该是 TLS 握手的开始(来自我所做的研究)。控制台显示与 CORS 相关的错误。我不知道为什么会这样-本地主机的起源不应该相同吗?服务器是否发送安全请求?
我已经尝试过这个socketio = SocketIO(app, cors_allowed_origins='*')
问题
中提到的,但问题仍然存在。这是日志输出,过去它会显示轮询 url:
我的 application.py 代码:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config["SECRET_KEY"] = 'secret?'
socketio = SocketIO(app, engineio_logger=True, logger=True)
@app.route("/", methods=["GET"])
def index():
return render_template("layout.html")
@socketio.on('message')
def handleMessage(msg):
print(msg)
emit(msg, broadcast=True)
if __name__ == '__main__':
socketio.run(app)
Javascript:
document.addEventListener('DOMContentLoaded', () => {
connectSocketIO();
addMessage();
});
var socket;
function connectSocketIO () {
socket = io.connect('http://' + document.domain + ':' + location.port);
socket.on('connect', () => {
console.log('client connected');
socket.on('disconnect', () => console.log('client disconnected'));
});
socket.on('message', (data) => {
console.log(data);
});
}
function addMessage () {
// emit a new message announcement when message is posted
document.querySelector('#btn').onclick = () => {
const message = document.querySelector('input').value;
socket.emit('message', {'message': message});
return false;
};
}
要求.txt
Flask
Flask-SocketIO
gunicorn
eventlet==0.24.1
编辑:
最初的问题似乎是由在 io.connect 中指定 https 协议引起的 - 更改已解决了乱码输出。
这导致 Firefox 抛出错误:
Firefox can't establish a connection to the server as wss://url
在 Chrome 中它可以工作,但连接更改为 http。两者都警告cookies滥用sameSite属性
Cookie "io" will be soon rejected because it has the "sameSite" attribute set to "none" or an invalid value, without the "secure" attribute.
Heroku Procfile:
web: gunicorn --worker-class eventlet -w 1 application:app
在服务器端,Heroku 的日志:
2020-07-28T12:41:43.350016+00:00 app[web.1]: https://flack-messaging-app.herokuapp.com is not an accepted origin.
2020-07-28T12:41:43.346991+00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=3&transport=polling&t=NELSMDM&sid=f25e5af236d347eaa3100951014be579" host=flack-messaging-app.herokuapp.com request_id=1041f8b4-71b8-4cf5-a321-75014d2ccde7 fwd="78.146.97.151" dyno=web.1 connect=1ms service=8ms status=400 bytes=182 protocol=https
2020-07-28T12:41:44.399195+00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=3&transport=polling&t=NELSMTk&sid=f25e5af236d347eaa3100951014be579" host=flack-messaging-app.herokuapp.com request_id=dba0c5f4-6afd-4621-ad7e-4c511911a714 fwd="78.146.97.151" dyno=web.1 connect=2ms service=3ms status=400 bytes=182 protocol=https
2020-07-28T12:41:44.402016+00:00 app[web.1]: https://flack-messaging-app.herokuapp.com is not an accepted origin.
2020-07-28T12:41:45.481764+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=3&transport=polling&t=NELSMkn" host=flack-messaging-app.herokuapp.com request_id=8ba7cc91-5e33-4113-a15d-84e5ceba8ca4 fwd="78.146.97.151" dyno=web.1 connect=1ms service=3ms status=200 bytes=385 protocol=https
2020-07-28T12:41:45.483979+00:00 app[web.1]: 5b1138c7e62a4ea2bff2beb55eb5241d: Sending packet OPEN data {'sid': '5b1138c7e62a4ea2bff2beb55eb5241d', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
2020-07-28T12:41:45.484100+00:00 app[web.1]: 5b1138c7e62a4ea2bff2beb55eb5241d: Sending packet MESSAGE data 0
2020-07-28T12:41:45.571836+00:00 app[web.1]: https://flack-messaging-app.herokuapp.com is not an accepted origin.
2020-07-28T12:41:45.566552+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=3&transport=websocket&sid=5b1138c7e62a4ea2bff2beb55eb5241d" host=flack-messaging-app.herokuapp.com request_id=d802cd1c-c875-4406-a75e-2c3ca2368de0 fwd="78.146.97.151" dyno=web.1 connect=0ms service=2ms status=400 bytes=187 protocol=https
2020-07-28T12:41:48.383640+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/socket.io/?EIO=3&transport=polling&t=NELSG6k&sid=f25e5af236d347eaa3100951014be579" host=flack-messaging-app.herokuapp.com request_id=26757146-e11f-43d6-a243-65172f72dd5e fwd="78.146.97.151" dyno=web.1 connect=1ms service=30001ms status=503 bytes=0 protocol=https
解决方案
好的,看起来有两个问题:
在客户端的 io.connect 中,使用了 connect 参数,
https:// + document.domain + location.port
但服务器使用的是 http://,因此导致输出乱码。更改https://
以window.location.protocol + '//' + 'rest_of_url'
修复乱码输出。Heroku 使用 https:// 但我的服务器配置为 http:// - 我仍然不确定要在 Flask 中更改哪些设置以使用另一个设置,但在我的 application.py 中,对于 Socket 构造函数,添加了
cors_allowed_origins='https://myurl'
固定wss 无法连接的问题。从那以后,我习惯于
cors_allowed_origins=['http://url', 'https://url']
允许安全和非安全访问。我对 Heroku 或 Flask 不够熟悉,无法强行将一个放在另一个之上,这个解决方案对我来说效果很好。
推荐阅读
- python - 运行 python 命令时在 ES 版本 7.3.2 上使用 elastalert 时出现问题
- c# - 泛型和 Nullable(类与结构)
- php - 是否有一个 CodeIgniter 函数可以帮助我们确定图像的宽度和高度?
- image-processing - 如何用 C 描述算法
- json - 如何在单个列表视图中加载多个列表视图?
- java - 如何对单个事务多次调用@Transactional 方法
- tensorflow - 如何使用 TextLineDataset 将文本写入文件
- java - Netlogo Api 控制器 - 获取表格视图
- java - 使用延迟加载面板时检票口无限重新加载页面
- wikidata - 从 OpenRefine 中的记录(而不是行)创建 wikidata 项目?