所以我有以下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,它处理进出请求。 它使用post请求( 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 ())然后再使用它发送数据。
但这个解决方案看起来有点难看。你能推荐另一种方法吗?
答案 0 :(得分:0)
这实际上是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
的副本。