【发布时间】:2021-11-20 14:46:32
【问题描述】:
我正在尝试在 Cog 中集成一个基本的 aiohttp 网络服务器(使用 discord-py 重写)。我正在为 cog 使用以下代码:
from aiohttp import web
import discord
from discord.ext import commands
class Youtube():
def __init__(self, bot):
self.bot = bot
async def webserver(self):
async def handler(request):
return web.Response(text="Hello, world")
app = web.Application()
app.router.add_get('/', handler)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, '192.168.1.111', 8999)
await self.bot.wait_until_ready()
await site.start()
def setup(bot):
yt = Youtube(bot)
bot.add_cog(yt)
bot.loop.create_task(yt.webserver())
它在启动机器人时工作正常。 但是如果我在机器人运行时重新加载 cog,我会遇到一个问题:
OSError: [Errno 10048] 尝试绑定地址时出错 ('192.168.1.111', 8999):每个socket地址只使用一次 (协议/网络地址/端口)通常是允许的
每次重新加载 cog 时,我都想不出一种简单/优雅的方式来释放和重新绑定。
我很想对此提出一些建议。最终目标是拥有一个支持 youtube pubsubhubbub 订阅的 cog。
可能只是有一种更好的方法可以将基本的网络服务器集成到我的机器人中。例如,我可以在启动机器人时使用一个守护进程(fork)(我已经有一个使用 HTTPServer 编写的网络服务器和一个可以处理 pubsubhubbub youtube 订阅的 BaseHTTPRequestHandler),但不知何故,我决定使用 aiohttp 将它集成到一个 cog 中:)
【问题讨论】:
-
如果你定义了 cog 的
__unload方法(不是协程),当 cog 被移除时会调用该方法。您的webserver方法应该通过self引用site,然后__unload可以用来调用site.stop -
def __unload(self): self.site.stop()我明白了:RuntimeWarning: coroutine 'BaseSite.stop' 从未等待过这是有道理的,但我不知道如何解决它:( -
可能是
self.bot.loop.run_until_complete(self.site.stop())?或类似的东西。 -
我选择了
asyncio.ensure_future(self.site.stop()),它似乎工作正常。谢谢!
标签: python python-3.x sockets discord.py aiohttp