托管在 Heroku 上的 Flask SocketIO 应用程序不使用 @socketio.on 事件?

Posted

技术标签:

【中文标题】托管在 Heroku 上的 Flask SocketIO 应用程序不使用 @socketio.on 事件?【英文标题】:Flask SocketIO app hosted on Heroku not using @socketio.on events? 【发布时间】:2022-01-11 05:19:21 【问题描述】:

正如您在下面发布的日志中看到的那样,从“前端”发送的数据正在通过。但唯一表明它通过的迹象是来自SocketIO 的日志记录选项,而不是来自我编写的代码。

在本地托管时一切正常。但是当我在 Heroku 上托管它时,它的工作方式就不一样了。我没有收到任何错误或崩溃或类似的情况,但我看到的成功通信的唯一迹象是来自 SocketIO 的日志记录(engine_iologger=Truelogger=True)。我定义的实际事件和函数似乎从未被使用过。

my_app.py

from flask import Flask, render_template
from flask_socketio import SocketIO, send, emit

app = Flask(__name__, template_folder=".")
app.config["SECRET_KEY"] = "fake key man"
socketio = SocketIO(app, cors_allowed_origins="*", engineio_logger=True, logger=True)


@app.route("/")
def index():
    return render_template("index.html")

    
@socketio.on("message")
def on_message(message):
    print(f"message: message")
    send("Hey, from the server")

if __name__ == "__main__":
    socketio.run(app)

过程文件

web: gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 my_app:app

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    button 
      height: 100px;
      width: 100px;
    
  </style>
</head>
<body>
  <h1>Hello this is the index</h1>
  <button>Button!</button>
  <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="static/script.js"></script>
</body>
</html>

script.js

function buttonClicked()
  console.log("sending message");
  socket.send("Hello, from the client");



document.querySelector("button").addEventListener("click", buttonClicked);
// const socket = io.connect("http://127.0.0.1:5000");
const socket = io.connect("http://total-confusion.herokuapp.com/socket.io");

socket.on("connect", () => 
  console.log("connected!");
)

socket.on("message", data => 
  console.log(`data: $data`);
)

Heroku 日志

2021-12-05T19:52:46.020757+00:00 heroku[web.1]: Starting process with command `gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 my_app:app`
2021-12-05T19:52:47.724970+00:00 heroku[web.1]: State changed from starting to up
2021-12-05T19:52:47.501740+00:00 app[web.1]: [2021-12-05 19:52:47 +0000] [4] [INFO] Starting gunicorn 20.1.0
2021-12-05T19:52:47.502072+00:00 app[web.1]: [2021-12-05 19:52:47 +0000] [4] [INFO] Listening at: http://0.0.0.0:29329 (4)
2021-12-05T19:52:47.502115+00:00 app[web.1]: [2021-12-05 19:52:47 +0000] [4] [INFO] Using worker: geventwebsocket.gunicorn.workers.GeventWebSocketWorker
2021-12-05T19:52:47.505637+00:00 app[web.1]: [2021-12-05 19:52:47 +0000] [9] [INFO] Booting worker with pid: 9
2021-12-05T19:52:48.278493+00:00 app[web.1]: Server initialized for gevent.
2021-12-05T19:52:50.660919+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4&transport=websocket&sid=7dk50RlRE2-P4ERfAAAC" host=total-confusion.herokuapp.com request_id=4115671c-13e5-4d0a-8143-2bb424683d48 fwd="174.70.52.92" dyno=web.1 connect=0ms service=314509ms status=101 bytes=129 protocol=http
2021-12-05T19:52:50.761966+00:00 heroku[router]: at=info method=GET path="/" host=total-confusion.herokuapp.com request_id=016c2145-a9e6-4144-8dde-24d49327d0db fwd="174.70.52.92" dyno=web.1 connect=0ms service=6ms status=200 bytes=808 protocol=http
2021-12-05T19:52:51.224044+00:00 heroku[router]: at=info method=GET path="/static/script.js" host=total-confusion.herokuapp.com request_id=d4c6c836-ec0e-41d3-9ade-92c8da94509d fwd="174.70.52.92" dyno=web.1 connect=0ms service=6ms status=200 bytes=691 protocol=http
2021-12-05T19:52:51.218524+00:00 app[web.1]: [2021-12-05 19:52:51 +0000] [9] [INFO] Worker exiting (pid: 9)
2021-12-05T19:52:51.363409+00:00 app[web.1]: [2021-12-05 19:52:51 +0000] [4] [INFO] Shutting down: Master
2021-12-05T19:52:51.512198+00:00 heroku[web.1]: Process exited with status 0
2021-12-05T19:52:51.455324+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4&transport=polling&t=NsCA1iy&sid=NwMwXg3pkqnB5t3UAAAA" host=total-confusion.herokuapp.com request_id=74a5cc6d-fa13-49c4-a835-53b8408579b3 fwd="174.70.52.92" dyno=web.1 connect=0ms service=1ms status=200 bytes=200 protocol=http
2021-12-05T19:52:51.392948+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4&transport=polling&t=NsCA1i3" host=total-confusion.herokuapp.com request_id=16381dc8-17dd-448d-8967-3704ab523483 fwd="174.70.52.92" dyno=web.1 connect=0ms service=1ms status=200 bytes=254 protocol=http
2021-12-05T19:52:51.451450+00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=4&transport=polling&t=NsCA1iw&sid=NwMwXg3pkqnB5t3UAAAA" host=total-confusion.herokuapp.com request_id=9a85832d-c36f-459c-aae9-c6a344555e87 fwd="174.70.52.92" dyno=web.1 connect=0ms service=1ms status=200 bytes=210 protocol=http
2021-12-05T19:52:51.393695+00:00 app[web.1]: NwMwXg3pkqnB5t3UAAAA: Sending packet OPEN data 'sid': 'NwMwXg3pkqnB5t3UAAAA', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000
2021-12-05T19:52:51.452253+00:00 app[web.1]: NwMwXg3pkqnB5t3UAAAA: Received packet MESSAGE data 0/socket.io,
2021-12-05T19:52:51.452457+00:00 app[web.1]: NwMwXg3pkqnB5t3UAAAA: Sending packet MESSAGE data 0/socket.io,"sid":"ax17karHdBzwH5yzAAAB"
2021-12-05T19:52:51.502132+00:00 app[web.1]: NwMwXg3pkqnB5t3UAAAA: Received request to upgrade to websocket
2021-12-05T19:52:51.862767+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4&transport=polling&t=NsCA1pM&sid=NwMwXg3pkqnB5t3UAAAA" host=total-confusion.herokuapp.com request_id=d640c10c-848b-41d0-900d-e2719472d9ed fwd="174.70.52.92" dyno=web.1 connect=0ms service=1ms status=200 bytes=157 protocol=http
2021-12-05T19:52:51.920149+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=4&transport=polling&t=NsCA1qC&sid=NwMwXg3pkqnB5t3UAAAA" host=total-confusion.herokuapp.com request_id=4cb0eb2d-564e-424c-ab66-9d8409f558d7 fwd="174.70.52.92" dyno=web.1 connect=0ms service=1ms status=200 bytes=157 protocol=http
2021-12-05T19:52:51.965935+00:00 app[web.1]: NwMwXg3pkqnB5t3UAAAA: Upgrade to websocket successful
2021-12-05T19:52:52.788905+00:00 app[web.1]: NwMwXg3pkqnB5t3UAAAA: Received packet MESSAGE data 2/socket.io,["message","Hello, from the client"]
2021-12-05T19:52:52.789077+00:00 app[web.1]: received event "message" from ax17karHdBzwH5yzAAAB [/socket.io]

【问题讨论】:

【参考方案1】:

发布后几分钟,我似乎已经解决了我自己的问题。如果我从 Heroku URL 中删除 /socket.io 位,那么它可以解决问题。我通过 添加 /socket.io 到本地 URL 的末尾确认了这一点,并且发生了相同的行为。甜蜜!

如果有人知道为什么,请告诉我!我不知道为什么我曾经使用过/socket.io,我认为这只是在尝试解决不同问题时发生的变化之一,并且它一直存在,所以我不了解它的作用。

【讨论】:

/socket.io端点不需要指定,由Socket.IO客户端自动添加。

以上是关于托管在 Heroku 上的 Flask SocketIO 应用程序不使用 @socketio.on 事件?的主要内容,如果未能解决你的问题,请参考以下文章

阻止 IP 地址访问我在 Heroku 上的 Flask 应用程序?

为啥我托管在 heroku 上的不和谐机器人随机关闭?

Discord Py - Heroku 托管 Bot 上的音乐命令

Heroku 托管烧瓶应用程序与 MySQL 抛出错误

禁止在 heroku 中托管 laravel 应用程序时,您无权访问此 xampp 服务器上的 /

使用托管在 S3 上的 create-react-app 来访问 Heroku API