Flask Socket.Io:导入后初始化的socketio的持久性
Posted
技术标签:
【中文标题】Flask Socket.Io:导入后初始化的socketio的持久性【英文标题】:Flask Socket.Io: Persistence of initialized socketio after import 【发布时间】:2018-02-10 00:47:56 【问题描述】:所以我有以下 websocket 服务器 api:
//x.py
......
import y
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@socketio.on('connected', namespace='/getDefects')
def connected():
y.set_client_sid(request.sid)
y.set_socketio(socketio)
@socketio.on('disconnect', namespace='/getDefects')
def disconnect():
print("Client disconnected")
def sendDefects(def, sid, socketio_input):
socketio = socketio_input
socketio.emit('defects', def, room=sid, namespace='/getDefects')
def processDefWithContext(text):
with app.test_request_context():
y.processDef(text)
@app.route('/Process', methods=['Post'])
def process():
text = request.form.get('text')
thread1 = Thread(target = processDefWithContext, args = (text,))
thread1.start()
response = "Ok"
return response
if __name__ == '__main__':
socketio.run(app, host='127.0.0.1', port=8080)
//y.py
import x
....
clientSid = 0
socketIo = 0
def set_client(sid):
clientSid = sid
def set_socketio(socket_in):
socketIo = socket_in
processDef(text):
....
def = ..
x.sendDefects(def, clientSid, socketio)
所以基本上 x.py 包含一个处理输入和输出请求的 web api。 它使用发布请求 (process()) 获取一些数据,然后在新线程中触发对该数据的一些处理。处理在 y.py 中完成。处理完成后,需要使用来自 x.py 的 websocket 将新数据发送到前端 所以 x.py 导入 y.py 并且 y.py 导入 x.py。问题是当我们从 y.py 调用函数来从 x.py 发送数据 (sendDefects(..)) 时,socketio 不再初始化并且将无法发送它.
到目前为止我找到的解决方案(我不是经验丰富的 Python 程序员)是将 socketio 从 x.py 发送到 y.py (set_socketio()) 并返回然后使用它发送数据。
但这个解决方案似乎有点难看。你能推荐另一种方法吗?
【问题讨论】:
【参考方案1】:这实际上是 Python 应用程序的主模块发生的奇怪事情的副作用。我假设您以以下方式启动您的应用程序:
python x.py
对吗?在这种情况下,您的x.py
模块被命名为__main__
,而不是x
。因此,您的应用程序的导入顺序最终会创建您的 x
模块的两个副本。这可能不是很清楚,所以让我描述一下您的应用中发生的情况:
x.py
,由于是主模块,所以在模块列表中存储为__main__
。
__main__
模块导入y
,存储为y
。
y
模块导入x
。在这里,解释器确定 x
尚未导入(因为 x
的现有实例称为 __main__
),因此它以该名称导入 x
的第二个副本。
所以当y
调用x
中的函数时,它正在调用具有未初始化socketio
变量的副本。 socketio
未初始化的原因是初始化被包装在 if __name__ == '__main__'
条件中,因此只会在第一个实例中运行。
那么你如何解决这个问题?在y.py
中,将import x
替换为:
import __main__ as x
这将确保您不会收到重复的 x
。
【讨论】:
嗨。好的,我明白了。感谢您的解决方案。我会试试看。以上是关于Flask Socket.Io:导入后初始化的socketio的持久性的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Flask 和 Socket.io 加入和离开房间的简明示例?
Flask socket.IO 服务器上的 Node.js Socket.io 客户端
Socket.io 与 flask-socketio python。如何设置套接字保持活动/超时