【问题标题】:Flask-SocketIO events in modules other than app.pyapp.py 以外的模块中的 Flask-SocketIO 事件
【发布时间】:2022-01-04 12:48:41
【问题描述】:

使用以下 Flask 命令启动 Flask 应用程序(根据 socketio.run(app))时,Flask SocketIO 服务器实现未接收客户端消息或事件触发器:flask run(在 http://127.0.0.1:5000 上)。

只输出GET和POST轮询:

127.0.0.1 - - [04/Jan/2022 13:18:26] "GET /socket.io/?EIO=4&transport=polling&t=Nub1htW HTTP/1.1" 200 -
127.0.0.1 - - [04/Jan/2022 13:18:26] "POST /socket.io/?EIO=4&transport=polling&t=Nub1i2I&sid=ELpMQjSfqpcXN731AAAA HTTP/1.1" 200 -
127.0.0.1 - - [04/Jan/2022 13:18:26] "GET /socket.io/?EIO=4&transport=polling&t=Nub1i2J&sid=ELpMQjSfqpcXN731AAAA HTTP/1.1" 200 -

项目结构:

├── Flask Web App
│   ├── app
│   │   ├── common
│   │   ├── distributed_manager
│   │   │   ├── distributed_manager.py
│   │   │   └── __init__.py
│   │   ├── __init__.py
│   │   ├── local_settings.py
│   │   ├── models
│   │   ├── settings.py
│   │   ├── static
│   │   │   ├── css
│   │   │   ├── img
│   │   │   └── js
│   │   │       ├── chat.js
│   │   │       └── responses.js
│   │   ├── templates
│   │   ├── util.py
│   │   └── views
│   │       ├── bot_views.py
│   │       ├── error_views.py
│   │       ├── __init__.py
│   │       ├── main_views.py
│   │       └── site_views.py
│   ├── flask_app.py

通过调用app/__init__.py 中定义的函数create_app() 在flask_app.py 中初始化应用程序。该函数返回一个包含 app 对象和 socketio 对象的元组,用于将这两者按以下方式组合(在 flask_app.py 中):

from app import create_app

app, socketio = create_app()

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

我已经设法通过以下方式将事件句柄函数放置在flask_app.py 中来处理来自客户端的消息:

from app import create_app

app, socketio = create_app()


@socketio.on("connect")
def handle_connection():
    print("Connected a client...")


@socketio.on("message")
def handle_message(msg):
    print("Client message: " + msg)


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

但出于关注点分离的原因并尽可能解耦应用程序,我想将服务器(编辑:服务器的处理功能)放在distributed_manager.py 中,因为稍后我计划将消息作为请求传递在这个模块中。

这是我的服务器 (distributed_manager.py):

from flask_socketio import send, emit
from flask_app import socketio


def ack_client():
    print("Message was received by the client.")

@socketio.on("connect")
def handle_connection(message):
    print("connected: " + message)


@socketio.on("message")
def handle_message(message):
    print(f"Received message: {message}")

和chat.js的客户:

var socket;
connectToSocket();
...
function connectToSocket(){
  socket = io.connect('http://' + document.domain + ':' + location.port);
  socket.on('connect', function() {
      socket.send('User has connected!');
  });
  // console.log("Connected to the socket.")
}

【问题讨论】:

  • 你在使用flask run吗?请尝试运行脚本。看文档,flask run 命令在配合 Socket.IO 使用时是有限制的,最好运行脚本让socketio.run(app)启动服务器。
  • 是的,我使用flask run 运行它,但在.flaskenv 文件中它被配置为FLASK_APP=flask_app。通过将处理函数移动到在 socketio.run(app) 之前加载的 init 函数解决了这个问题(见答案)。

标签: python flask flask-socketio


【解决方案1】:

所以,我已经连接了我的两个脑细胞,并发现我的 distributed_manager 模块是在 socketio.run(app) 调用之后和创建应用程序之后执行的,因此必须在它之前定义 @socketio.on... 函数,特别是在我的解决方案中app/__init__.py,它创建了 app 和 socketio 对象。

【讨论】:

    猜你喜欢
    • 2021-12-23
    • 2022-01-03
    • 2022-12-16
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多