问题描述
我是服务器开发的新手,所以请多多关照... 我正在开发一个测试应用程序,它启动一个 Flask-socketio 服务器,在与客户端交互后,它需要关闭并打开另一个实例。 然而这是不可能的 我收到错误
File "C:\python39\lib\site-packages\eventlet\convenience.py",line 78,in listen
sock.bind(addr)
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
如何以编程方式关闭服务器? 我在这里查看了答案 How to stop flask application without using ctrl-c 并且使用过程确实可以解决问题。 但我真的不想有一个单独的进程,因为在进程之间共享变量太棘手了。
我也没有从同一篇文章中了解到如何从服务器向服务器本身发送请求以关闭 Flask 应用程序。 这是我的代码示例
import socketio
import eventlet
import eventlet.wsgi
from flask import Flask,render_template
import socket
import threading
import time
ip_addr=socket.gethostbyname(socket.gethostname())
appFlask = Flask(__name__)
sio = socketio.Server( ) #engineio_logger=True,logger=True)
# wrap Flask application with engineio's middleware
app = socketio.Middleware(sio,appFlask)
@sio.on('connect')
def connect(sid,environ):
print('connect ',sid)
@sio.on('message')
def message(sid,data):
print('message '+data,data)
@sio.on('disconnect')
def disconnect(sid):
print('disconnect ',sid)
@sio.on('result')
def result(sid,data):
print('result ',sid)
def worker1():
socket_port=3000
eventlet.wsgi.server(eventlet.listen((ip_addr,socket_port)),app)
if __name__ == '__main__':
sio.start_background_task(worker1)
# do some stuff and interact with the client
sio.sleep(2)
# how can I close the server so that I can do the following?
sio.start_background_task(worker1)
import socketio
import eventlet
import eventlet.wsgi
from flask import Flask,render_template
import socket
import threading
import time
import requests
from flask import request
from flask_socketio import SocketIO
ip_addr=socket.gethostbyname(socket.gethostname())
socket_port=3000
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
sio = SocketIO(app)
@app.route('/stop')
def stop():
sio.stop()
@sio.on('connect')
def connect(sid,sid)
def worker1():
eventlet.wsgi.server(eventlet.listen((ip_addr,app)
if __name__ == '__main__':
eventlet_thr=sio.start_background_task(worker1)
# do some stuff and interact with the client
sio.sleep(2)
# Now wait that the server is stopped
# invoke in a different process a request to stop
eventlet_thr.join()
# how can I close the server so that I can do the following?
sio.start_background_task(worker1)
解决方法
你用的似乎是eventlet web server,所以问题是如何停止eventlet web server,Flask-SocketIO与服务器无关。
为方便起见,Flask-SocketIO 提供了 stop()
方法,您必须从处理程序内部调用该方法。我不确定当服务器在不是主线程的线程上运行时这是否会起作用,但您必须对其进行测试。
所以基本上你需要做的是添加一个强制服务器退出的端点,可能是这样的:
@app.route('/stop')
def stop():
sio.stop()
return ''
那么您可以按如下方式启动和停止服务器:
if __name__ == '__main__':
thread = sio.start_background_task(worker1)
# do some stuff and interact with the client
requests.get('http://localhost:5000/stop')
thread.join()