如何在线程中 运行 aiohttp 服务器?
How to run an aiohttp server in a thread?
这个线程中的 aiohttp 服务器示例因 RuntimeError: There is no current event loop in thread 'Thread-1'.
错误而失败:
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)])
web.run_app(app)
t = threading.Thread(target=aiohttp_server)
t.start()
如何运行线程中的aiohttp服务器?
我们必须在主线程中使用app.make_handler
处理程序,例如:
import asyncio
import threading
from aiohttp import web
loop = asyncio.get_event_loop()
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()
server = loop.create_server(handler, host='127.0.0.1', port=8080)
def aiohttp_server():
loop.run_until_complete(server)
loop.run_forever()
t = threading.Thread(target=aiohttp_server)
t.start()
在主线程中创建 handler
并在子线程中手动创建事件循环。
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()
更新
对于新的aiohttp
,请使用以下内容,感谢@Auyer 的通知。
import asyncio
import threading
from aiohttp import web
def aiohttp_server():
def say_hello(request):
return web.Response(text='Hello, world')
app = web.Application()
app.add_routes([web.get('/', say_hello)])
runner = web.AppRunner(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()
t = threading.Thread(target=run_server, args=(aiohttp_server(),))
t.start()
有一个新的 API 用于此用例:
https://docs.aiohttp.org/en/stable/web_advanced.html#application-runners
from aiohttp import web
import asyncio
async def healthz(request):
return web.Response(text="OK")
app = web.Application()
app.add_routes([web.get("/", healthz)])
async def runner():
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, "localhost", 8080)
await site.start()
loop = asyncio.get_event_loop()
loop.run_until_complete(runner())
可以使用web.run_app
,只需创建一个新的事件循环(并设置handle_signals=False
以避免RuntimeError: set_wakeup_fd only works in main thread
):
import threading
import asyncio
from aiohttp import web
def aiohttp_server():
def say_hello(request):
return web.Response(text='Hello, world')
asyncio.set_event_loop(asyncio.new_event_loop()) # create a new event loop here
app = web.Application(debug=True)
app.add_routes([web.get('/', say_hello)])
web.run_app(app, handle_signals=False)
这个线程中的 aiohttp 服务器示例因 RuntimeError: There is no current event loop in thread 'Thread-1'.
错误而失败:
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)])
web.run_app(app)
t = threading.Thread(target=aiohttp_server)
t.start()
如何运行线程中的aiohttp服务器?
我们必须在主线程中使用app.make_handler
处理程序,例如:
import asyncio
import threading
from aiohttp import web
loop = asyncio.get_event_loop()
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()
server = loop.create_server(handler, host='127.0.0.1', port=8080)
def aiohttp_server():
loop.run_until_complete(server)
loop.run_forever()
t = threading.Thread(target=aiohttp_server)
t.start()
在主线程中创建 handler
并在子线程中手动创建事件循环。
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()
更新
对于新的aiohttp
,请使用以下内容,感谢@Auyer 的通知。
import asyncio
import threading
from aiohttp import web
def aiohttp_server():
def say_hello(request):
return web.Response(text='Hello, world')
app = web.Application()
app.add_routes([web.get('/', say_hello)])
runner = web.AppRunner(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()
t = threading.Thread(target=run_server, args=(aiohttp_server(),))
t.start()
有一个新的 API 用于此用例:
https://docs.aiohttp.org/en/stable/web_advanced.html#application-runners
from aiohttp import web
import asyncio
async def healthz(request):
return web.Response(text="OK")
app = web.Application()
app.add_routes([web.get("/", healthz)])
async def runner():
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, "localhost", 8080)
await site.start()
loop = asyncio.get_event_loop()
loop.run_until_complete(runner())
可以使用web.run_app
,只需创建一个新的事件循环(并设置handle_signals=False
以避免RuntimeError: set_wakeup_fd only works in main thread
):
import threading
import asyncio
from aiohttp import web
def aiohttp_server():
def say_hello(request):
return web.Response(text='Hello, world')
asyncio.set_event_loop(asyncio.new_event_loop()) # create a new event loop here
app = web.Application(debug=True)
app.add_routes([web.get('/', say_hello)])
web.run_app(app, handle_signals=False)