app.py 以外模块中的 Flask-SocketIO 事件

Flask-SocketIO events in modules other than app.py

Flask SocketIO 服务器实现在使用 flask 命令启动 Flask 应用程序(根据 socketio.run(app))时未接收客户端消息或事件触发器: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

应用程序在 flask_app.py 中通过调用 app/__init__.py 中定义的函数 create_app() 进行初始化。此函数 returns 一个包含 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.")
}

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