Flask Socket.Io:导入后初始化socketio的持久性

时间:2018-02-10 00:47:57

标签: python flask websocket python-import flask-socketio

所以我有以下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 ())然后再使用它发送数据。

但这个解决方案看起来有点难看。你能推荐另一种方法吗?

1 个答案:

答案 0 :(得分:0)

这实际上是Python应用程序中主模块发生的奇怪事情的副作用。我假设你开始申请:

python x.py

正确?在这种情况下,您的x.py模块名为__main__,而不是x。因此,应用程序的导入序列最终会创建x模块的两个副本。这可能不是很清楚,所以让我来描述您的应用中发生的事情:

  • python解释器导入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的副本。