首页 > 解决方案 > 20分钟后的Python Dicord bot ConnectionResetError

问题描述

我编写了一个不和谐的机器人,它将使用 wordpress api 验证许可证密钥。

如果用户说: !key xxx-xxx-xxx-xxx

Bot 通过密钥检查许可证是否有效,如果有效,它将开始插入表格并回复用户。

如果许可证无效(错误 404),它只会响应用户。

代码如下:

# bot.py
import os
import aiohttp
from urllib.request import urlopen
import json
import mysql.connector
import discord
import logging
from discord.ext import commands
from discord.utils import get

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, filename="logfile", filemode="a+",
                        format="%(asctime)-15s %(levelname)-8s %(message)s")

TOKEN ='TOKEN'
GUILD_ID = 'ID'

bot = commands.Bot(command_prefix='!')


@bot.event
async def on_ready():
    logging.info('------')
    logging.info('Logged in as')
    logging.info(bot.user.name)
    logging.info(bot.user.id)
    logging.info('------')

@bot.event
async def on_member_join(member):
    await member.create_dm()
    await member.dm_channel.send('bla')

def remove_prefix(str, prefix):
    return str.lstrip(prefix)

@bot.command(name='g')
async def rename(ctx, name):
    await bot.user.edit(username=name)

@bot.command(name='key', pass_context=True)
async def nine_nine(ctx):
    if ctx.channel.id == ctx.author.dm_channel.id: 

            cs = 'cs_***'
            ck = 'ck_5***'
            username = ctx.message.author.name
            discordMemberID = ctx.message.author.id
            userMessage = ctx.message.content
            key = remove_prefix(userMessage, '!key ')
            server =  bot.get_guild(id)
            role = discord.utils.get(server.roles, id=id)
            member = server.get_member(ctx.message.author.id)
            user3 = ctx.message.author.id
            logging.info( 'DicordUserId %s'%user3)
            session = aiohttp.ClientSession()
            r = await session.get('https:/mywebsite.com/wp-json/lmfwc/v2/licenses/activate/' + key + '?' +  'consumer_key=' + ck + '&consumer_secret=' + cs )
            logging.info(r.status)
            if r.status == 200:
                r.close()
                    logging.info("R**")
                    print("**")
                    cnx = mysql.connector.connect(host=....)                                
                    if cnx.is_connected():
                        db_Info = cnx.get_server_info()
                        logging.info('**')
                        cursor = cnx.cursor(buffered=True)
                        logging.info("You're connected to database: ")
                        cursor.execute(***)
                        if  cursor.rowcount == 0:
                            ***
                            cursor.execute(***)
                            cnx.commit()
                            logging.info(**)
                            cursor.close()
                            cnx.close())
                            if member:
                                await member.add_roles(role)
                                await ctx.send("**)#
                                await ctx.send("**")"
                            await ctx.send('***')   
                            cursor.close()
                            cnx.close()
                            logging.info("Closed Connection.")
                    else: 
                         logging.error("Conection Error")
                         await ctx.send('Connection Problems. Please Contact an Administrator of the Server!')

            elif r.status == 404:
                r.close()
                    print('HTTPError: {}'.format(e.code))
                    await ctx.send('***')
    else:
        logging.warning("Private command only")
        await ctx.send("Private command only. Please DM me with  the '!key' command :)")  

bot.run(TOKEN)

它运行得非常好,但大约 20 分钟后,连接就会出现超时,并且机器人首先会响应 !key 命令:

Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> 
======= RESTART: C:\Users\Administrator\Desktop\Discord Bot\LicenseBot.py ======
Ignoring exception in command key:
Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\aiohttp\connector.py", line 936, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
  File "C:\Program Files\Python37\lib\asyncio\base_events.py", line 985, in create_connection
    ssl_handshake_timeout=ssl_handshake_timeout)
  File "C:\Program Files\Python37\lib\asyncio\base_events.py", line 1013, in _create_connection_transport
    await waiter
  File "C:\Program Files\Python37\lib\asyncio\selector_events.py", line 814, in _read_ready__data_received
    data = self._sock.recv(self.max_size)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "C:\Users\Administrator\Desktop\Discord Bot\LicenseBot.py", line 72, in nine_nine
    r = await session.get('URL + key + '?' +  'consumer_key=' + ck + '&consumer_secret=' + cs )
  File "C:\Program Files\Python37\lib\site-packages\aiohttp\client.py", line 483, in _request
    timeout=real_timeout
  File "C:\Program Files\Python37\lib\site-packages\aiohttp\connector.py", line 523, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "C:\Program Files\Python37\lib\site-packages\aiohttp\connector.py", line 859, in _create_connection
    req, traces, timeout)
  File "C:\Program Files\Python37\lib\site-packages\aiohttp\connector.py", line 1004, in _create_direct_connection
    raise last_exc
  File "C:\Program Files\Python37\lib\site-packages\aiohttp\connector.py", line 986, in _create_direct_connection
    req=req, client_error=client_error)
  File "C:\Program Files\Python37\lib\site-packages\aiohttp\connector.py", line 943, in _wrap_create_connection
    raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host URL.com:443 ssl:default [An existing connection was forcibly closed by the remote host]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\discord\ext\commands\bot.py", line 903, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Program Files\Python37\lib\site-packages\discord\ext\commands\core.py", line 855, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Program Files\Python37\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ClientConnectorError: Cannot connect to host URL.com:443 ssl:default [An existing connection was forcibly closed by the remote host]

在此错误之后,我通常可以再次填写 !key 命令,新用户将收到一条欢迎消息。

已经尝试过库请求而不是 urllib

也尝试了带有会话和 session.close() 的请求。

通过 AWS EC2 托管。Otehr 服务运行良好。

标签: pythonpython-3.xpython-requestsdiscord.pyurllib

解决方案


如果您认为这不是您的互联网连接,那么 Discord 会关闭连接。连接不良或阻塞代码(time.sleep、请求、同步 SQL 访问、密集计算/图像处理,或者您只是做得太快,即发送太多消息。


推荐阅读