如何解决Python 问题:无法在单独的线程或事件循环中运行连接 aiohttp 服务器
我一直无法在后台使用 aiohttp 获取连接服务器,因此在启动网络服务器时主线程不会挂起。
我想我可能可以通过使用 asyncio 并为其他所有内容创建一个任务,但是我正在编写一个可供其他人和公司重用的库,而我没有能力执行那种设计模式单方面通用。
我已经开始工作了(来自 https://newbedev.com/how-to-run-an-aiohttp-server-in-a-thread):
import asyncio
import threading
from aiohttp import web
def aiohttp_server():
def say_hello(request):
return web.Response(text='Hello,world')
app = web.Application(debug=True)
app.add_routes([web.get('/',say_hello)])
handler = app.make_handler()
return handler
def run_server(handler):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
server = loop.create_server(handler,host='127.0.0.1',port=8089)
loop.run_until_complete(server)
loop.run_forever()
t = threading.Thread(target=run_server,args=(aiohttp_server(),))
t.start()
for i in range(50000):
print('Hi from Main Thread')
time.sleep(5)
这会使服务器保持运行状态,然后允许主线程继续运行。
但是,当我尝试使用此代码并使用以下代码启动连接服务器时,我无法启动并运行,我在第 2 天,我必须开始行动.我希望有人看到我做过或误解的愚蠢的事情,并能告诉我如何解决它。
def initializeServertest():
app = connexion.AioHttpApp(__name__,port=8080,specification_dir='openAPISpecs/',# https://github.com/OpenAPITools/openapi-generator/issues/1322
only_one_api=True
)
app.add_api('openAPISpec.json',arguments={'title': 'Instrument and HUB API'},pythonic_params=True,validate_responses=True
)
# Configure default CORS settings.
cors = aiohttp_cors.setup(app.app,defaults={
"*": aiohttp_cors.ResourceOptions(allow_credentials=True,expose_headers="*",allow_headers="*",allow_methods=["GET","POST","PUT"]
)
})
# Configure CORS on every route
for route in list(app.app.router.routes()):
cors.add(route)
# Now create a runner we will start later
runner = web.AppRunner(app.create_app())
return runner
def run_server(runner):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(runner.setup())
site = web.Tcpsite(runner,'localhost',8080)
loop.run_until_complete(site.start())
loop.run_forever()
def StartServerInBackground():
t = threading.Thread(target=run_server,args=(initializeServertest(),))
t.start()
当我执行此操作时,我恢复了主线程,但 Web 服务器不响应任何请求。
任何帮助将不胜感激
解决方法
好的,这是我想出的解决方案:
import connexion
from aiohttp import web
from aiohttp_cors
import threading
app = {}
apprunner = {}
def _initializeServer():
# use module level app
global app
app = connexion.AioHttpApp(__name__,port=8080,specification_dir='openAPISpecs/',# https://github.com/OpenAPITools/openapi-generator/issues/1322
only_one_api=True
)
app.add_api('openAPISpec.json',arguments={'title': 'Analyzer and HUB API'},pythonic_params=True,validate_responses=True,# doesn't always work with JSON bodies: https://github.com/zalando/connexion/issues/837
strict_validation=True
)
# Configure default CORS settings.
cors = aiohttp_cors.setup(app.app,defaults={
"*": aiohttp_cors.ResourceOptions(allow_credentials=True,expose_headers="*",allow_headers="*",allow_methods=["GET","POST","PUT","DELETE"]
)
})
# Configure CORS on every route
for route in list(app.app.router.routes()):
cors.add(route)
def _startServer_NonBlocking(runner):
#store runner at module level for use later
global apprunner
apprunner = runner
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(runner.setup())
site = web.TCPSite(runner,'localhost',8080)
loop.run_until_complete(site.start())
loop.run_forever()
def startServer_NonBlocking():
# grab module level serverRunning for comparison in next line
global serverRunning
# if the server isn't already running
if(serverRunning == False):
# configure new thread and start it
newThread = threading.Thread(target=_startServer_NonBlocking,args=(_initializeServer_NonBlocking(),))
newThread.start()
# set flag that the server is running so we don't ever try to start it again
serverRunning = True
秘诀在于发现您必须使用 app.app 来获取运行程序,然后您可以稍后使用它来按照连接文档中的食谱进行设置。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。