#python #flask #heroku #gunicorn #flask-socketio
#python #flask #heroku #gunicorn #flask-socketio
Вопрос:
Идея заключается в том, чтобы создать серверную часть, использующую Flask SocketIO и размещенную на Heroku, и отдельный интерфейс, который может использовать этот сервер.
Я могу нормально разместить серверную часть (я могу сказать, что это работает, потому что я добавил простой маршрут Flask, который я могу просмотреть по URL-адресу приложения Heroku), но есть много проблем с подключением интерфейса к серверной части.
server.py (серверная часть с использованием Flask SocketIO)
from flask import Flask
from flask_socketio import SocketIO, send
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecret'
socketio = SocketIO(app, cors_allowed_origins='*', engineio_logger=True, logger=True)
@socketio.on('message')
def handleMessage(msg):
print('Message: ' msg)
send(msg, broadcast=True)
@app.route("/")
def index():
return "<h1>This is the index</h1>"
if __name__ == '__main__':
socketio.run(app)
index.html (отдельный интерфейс)
(Также не уверен, должен ли бит внутри io.connect
быть http, https, wss, но я попробовал все три с одинаковыми результатами)
<html>
<head>
<title>Chat Room</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.0/socket.io.js" integrity="sha512-nYuHvSAhY5lFZ4ixSViOwsEKFvlxHMU2NHts1ILuJgOS6ptUmAGt/0i5czIgMOahKZ6JN84YFDA mCdky7dD8A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
var socket = io.connect('wss://young-scrubland-90415.herokuapp.com/');
socket.on('connect', function() {
socket.send('User has connected!');
});
socket.on('message', function(msg) {
$("#messages").append('<li>' msg '</li>');
console.log('Received message');
});
$('#sendbutton').on('click', function() {
socket.send($('#myMessage').val());
$('#myMessage').val('');
});
});
</script>
<ul id="messages"></ul>
<input type="text" id="myMessage">
<button id="sendbutton">Send</button>
</body>
</html>
Что происходит, так это куча ошибок в консоли разработчика интерфейса: в основном 400 (BAD REQUEST)
s, но также и много WebSocket connection to '<URL>' failed: WebSocket is closed before the connection is established
. Время от времени я вижу Received message
, что это означает, что интерфейс успешно подключен к серверной части, но после этого будут продолжать отображаться те же ошибки.
Procfile
web: gunicorn server:app
Я не уверен, где действительно «начинаются» журналы Heroku, но вот часть журналов:
2021-11-30T18:29:46.288972 00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4amp;transport=pollingamp;t=Nro6z5mamp;sid=NDhJT0z96qLOucrWAAAs" host=young-scrubland-90415.herokuapp.com request_id=cf82a068-664a-4d8c-9143-85070cf7c2cd fwd="174.243.112.185" dyno=web.1 connect=0ms service=23649ms status=400 bytes=276 protocol=https
2021-11-30T18:29:46.284545 00:00 app[web.1]: HPmyKr8vdxbU4f1gAAAq: Sending packet PING data None
2021-11-30T18:29:46.285088 00:00 app[web.1]: 10.1.94.221 - - [30/Nov/2021:18:29:46 0000] "GET /socket.io/?EIO=4amp;transport=pollingamp;t=Nro6yq6amp;sid=HPmyKr8vdxbU4f1gAAAq HTTP/1.1" 200 1 "http://localhost:5500/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
2021-11-30T18:29:46.285645 00:00 app[web.1]: Invalid session NDhJT0z96qLOucrWAAAs
2021-11-30T18:29:46.285985 00:00 app[web.1]: 10.1.24.245 - - [30/Nov/2021:18:29:46 0000] "GET /socket.io/?EIO=4amp;transport=pollingamp;t=Nro6z5mamp;sid=NDhJT0z96qLOucrWAAAs HTTP/1.1" 400 17 "http://localhost:5500/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
2021-11-30T18:29:46.286451 00:00 app[web.1]: Invalid session NDhJT0z96qLOucrWAAAs
2021-11-30T18:29:46.286802 00:00 app[web.1]: 10.1.95.96 - - [30/Nov/2021:18:29:46 0000] "POST /socket.io/?EIO=4amp;transport=pollingamp;t=Nro6z5kamp;sid=NDhJT0z96qLOucrWAAAs HTTP/1.1" 400 17 "http://localhost:5500/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
2021-11-30T18:29:46.472483 00:00 app[web.1]: NDhJT0z96qLOucrWAAAs: Failed websocket upgrade, expected UPGRADE packet, received None instead.
2021-11-30T18:29:46.472867 00:00 app[web.1]: [2021-11-30 18:29:46 0000] [9] [ERROR] Socket error processing request.
2021-11-30T18:29:46.472868 00:00 app[web.1]: Traceback (most recent call last):
2021-11-30T18:29:46.472869 00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/workers/sync.py", line 136, in handle
2021-11-30T18:29:46.472869 00:00 app[web.1]: self.handle_request(listener, req, client, addr)
2021-11-30T18:29:46.472870 00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/workers/sync.py", line 194, in handle_request
2021-11-30T18:29:46.472870 00:00 app[web.1]: util.reraise(*sys.exc_info())
2021-11-30T18:29:46.472870 00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/util.py", line 626, in reraise
2021-11-30T18:29:46.472871 00:00 app[web.1]: raise value
2021-11-30T18:29:46.472872 00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/workers/sync.py", line 185, in handle_request
2021-11-30T18:29:46.472872 00:00 app[web.1]: resp.write(item)
2021-11-30T18:29:46.472873 00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/http/wsgi.py", line 326, in write
2021-11-30T18:29:46.472873 00:00 app[web.1]: self.send_headers()
2021-11-30T18:29:46.472873 00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/http/wsgi.py", line 322, in send_headers
2021-11-30T18:29:46.472874 00:00 app[web.1]: util.write(self.sock, util.to_bytestring(header_str, "latin-1"))
2021-11-30T18:29:46.472874 00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/gunicorn/util.py", line 287, in write
2021-11-30T18:29:46.472874 00:00 app[web.1]: sock.sendall(data)
2021-11-30T18:29:46.472875 00:00 app[web.1]: OSError: [Errno 9] Bad file descriptor
2021-11-30T18:29:46.285740 00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=4amp;transport=pollingamp;t=Nro6z5kamp;sid=NDhJT0z96qLOucrWAAAs" host=young-scrubland-90415.herokuapp.com request_id=4900fc50-0027-4140-bc7c-decfd52d1684 fwd="174.243.112.185" dyno=web.1 connect=0ms service=23646ms status=400 bytes=276 protocol=https
2021-11-30T18:29:46.285836 00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4amp;transport=pollingamp;t=Nro6yq6amp;sid=HPmyKr8vdxbU4f1gAAAq" host=young-scrubland-90415.herokuapp.com request_id=64ebc4b0-81a5-4d8b-a66a-3871dd308e6f fwd="174.243.112.185" dyno=web.1 connect=0ms service=24795ms status=200 bytes=265 protocol=https
2021-11-30T18:29:46.479546 00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4amp;transport=websocketamp;sid=NDhJT0z96qLOucrWAAAs" host=young-scrubland-90415.herokuapp.com request_id=5ddd2737-7437-4cb4-94b4-7aeda8dbdf1c fwd="174.243.112.185" dyno=web.1 connect=0ms service=23900ms status=101 bytes=202 protocol=https
2021-11-30T18:29:47.292647 00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4amp;transport=pollingamp;t=Nro737D" host=young-scrubland-90415.herokuapp.com request_id=8ec81170-0580-48ee-a288-78cf9aa7b5e8 fwd="174.243.112.185" dyno=web.1 connect=0ms service=1ms status=200 bytes=362 protocol=https
2021-11-30T18:29:47.410920 00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4amp;transport=pollingamp;t=Nro738jamp;sid=Ehmhduh_5Wnt0SgHAAAs" host=young-scrubland-90415.herokuapp.com request_id=131ec4ae-50f0-4468-a022-e2508d3a421c fwd="174.243.112.185" dyno=web.1 connect=0ms service=1ms status=400 bytes=276 protocol=https
2021-11-30T18:29:47.291224 00:00 app[web.1]: Ehmhduh_5Wnt0SgHAAAs: Sending packet OPEN data {'sid': 'Ehmhduh_5Wnt0SgHAAAs', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000}
2021-11-30T18:29:47.291871 00:00 app[web.1]: 10.1.94.221 - - [30/Nov/2021:18:29:47 0000] "GET /socket.io/?EIO=4amp;transport=pollingamp;t=Nro737D HTTP/1.1" 200 97 "http://localhost:5500/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
2021-11-30T18:29:47.391407 00:00 app[web.1]: Invalid session Ehmhduh_5Wnt0SgHAAAs
2021-11-30T18:29:47.391783 00:00 app[web.1]: 10.1.94.221 - - [30/Nov/2021:18:29:47 0000] "POST /socket.io/?EIO=4amp;transport=pollingamp;t=Nro738gamp;sid=Ehmhduh_5Wnt0SgHAAAs HTTP/1.1" 400 17 "http://localhost:5500/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
2021-11-30T18:29:47.410001 00:00 app[web.1]: Invalid session Ehmhduh_5Wnt0SgHAAAs
2021-11-30T18:29:47.410470 00:00 app[web.1]: 10.1.24.245 - - [30/Nov/2021:18:29:47 0000] "GET /socket.io/?EIO=4amp;transport=pollingamp;t=Nro738jamp;sid=Ehmhduh_5Wnt0SgHAAAs HTTP/1.1" 400 17 "http://localhost:5500/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
2021-11-30T18:29:47.489672 00:00 app[web.1]: Invalid session Ehmhduh_5Wnt0SgHAAAs
2021-11-30T18:29:47.490037 00:00 app[web.1]: 10.1.94.221 - - [30/Nov/2021:18:29:47 0000] "POST /socket.io/?EIO=4amp;transport=pollingamp;t=Nro73AQamp;sid=Ehmhduh_5Wnt0SgHAAAs HTTP/1.1" 400 17 "http://localhost:5500/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
2021-11-30T18:29:47.490707 00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=4amp;transport=pollingamp;t=Nro73AQamp;sid=Ehmhduh_5Wnt0SgHAAAs" host=young-scrubland-90415.herokuapp.com request_id=3e36cba7-1de6-435c-914f-9fbefcd7758c fwd="174.243.112.185" dyno=web.1 connect=0ms service=1ms status=400 bytes=276 protocol=https
2021-11-30T18:29:47.392465 00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=4amp;transport=pollingamp;t=Nro738gamp;sid=Ehmhduh_5Wnt0SgHAAAs" host=young-scrubland-90415.herokuapp.com request_id=c6fab832-5bf5-4ed4-ab0c-0be04444275e fwd="174.243.112.185" dyno=web.1 connect=0ms service=1ms status=400 bytes=276 protocol=https
2021-11-30T18:29:49.291443 00:00 app[web.1]: 4sYf-4nVDG980gzKAAAt: Sending packet OPEN data {'sid': '4sYf-4nVDG980gzKAAAt', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000}
2021-11-30T18:29:49.291665 00:00 app[web.1]: EGCwP7PO8ItOkmLtAAAo: Client is gone, closing socket
2021-11-30T18:29:49.291829 00:00 app[web.1]: EGCwP7PO8ItOkmLtAAAo: Client is gone, closing socket
Я часами гуглил и гуглил (вчера, может быть, 2-3 часа, а сегодня я работаю над этим где-то 2-3 часа) и не добился большого прогресса. Я МОЛЮСЬ, чтобы кто-нибудь здесь смог помочь.
Комментарии:
1. Раздел устранения неполадок документов Flask-SocketIO содержит инструкции о том, как включить ведение журнала. Сделайте это, а затем обновите свои журналы Heroku, поскольку вставленный вами раздел журналов не содержит достаточной информации для диагностики проблемы. Кроме того, когда вы читаете документы, просмотрите раздел deployment, который относится к вашей ситуации, чтобы убедиться, что вы все делаете правильно. Команда Gunicorn, которую вы имеете здесь, выглядит для меня неправильно.
2. @Miguel Я не совсем понимаю, что ты говоришь. Что касается ведения журнала, вы имеете
engineio_logger
logger
в виду аргументы ключевого слова and / or при инициализацииSocketIO
объекта? Я установил для обоих из них значение True, и я не уверен, какие другие параметры ведения журнала вы имеете в виду. Что касается неправильной команды Gunicorn, с тех пор я изменил Procile наweb: gunicorn -k gevent -w 1 server:app
(из документов). Но у меня все еще возникают проблемы, и я не понимаю Gunicorn или gevent или что-то в этом роде достаточно хорошо, чтобы знать, куда идти дальше.3. @Miguel Я также не уверен, какую часть журналов мне нужно вставить. Я создал совершенно новое приложение Heroku и попытался скопировать все журналы (поскольку на данный момент приложение работает всего 10 минут), но слишком много символов для добавления в исходное сообщение. Итак, вот ссылка на вставку: pastebin.com/0WdMxq0E . Мне определенно кажется ленивым просто копировать и вставлять весь журнал и просить вас разобраться в нем, но, как я уже сказал, я не знаю, какие части имеют отношение к делу :/
4. Вы заметили в журналах этот сокет. IO говорит, что «сервер инициализирован для eventlet»? Тем не менее, вы используете gevent. Это, скорее всего, часть проблемы. Удалите eventlet или явно сообщите Socket. Ввод-вывод, который вы хотите использовать в gevent. Смотрите
async_mode
Опцию В документации для получения дополнительной информации об этом.