我编写了一个python电报机器人,以摆脱没有启动记录的计时器和时钟。
但不幸的是,在测试中,我遇到了一个我无法理解的奇怪问题——每次作业队列中的作业在选定的15分钟延迟后执行时,都会发生HTTPError(http.client.RemoteDisconnected: Remote end closed connection without response
)
我尝试用谷歌搜索这个问题,并在代码中添加了一些关键字参数timeout=3600
,但这个更改对bot的性能没有影响。
有人能澄清我不明白的事情吗?
事先非常感谢
以下是我的代码,由两个文件组成:
test_bot.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import pytz
import telegram_bot_config as t
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton, ParseMode
from telegram.ext import Updater, CommandHandler, CallbackContext, CallbackQueryHandler, Defaults
import datetime as dt
# Enable logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
)
logger = logging.getLogger(__name__)
def make_kb():
keyboard = [
[InlineKeyboardButton("Send message in 15 minutes", callback_data=t.BUTTON_LABEL1)],
[InlineKeyboardButton("Send message in 4 hours", callback_data=t.BUTTON_LABEL2)],
]
reply_markup = InlineKeyboardMarkup(keyboard)
return reply_markup
def start(update: Update, context: CallbackContext) -> None:
"""Sends a message with three inline buttons attached."""
reply_markup = make_kb()
update.message.reply_text('Please choose:', reply_markup=reply_markup)
def alarm(context: CallbackContext) -> None:
"""Send the alarm message."""
job = context.job
dt_now = dt.datetime.now()
dt_now_str = dt.datetime.strftime(dt_now, '%Y-%m-%d %H:%M:%S')
delta_dt = (dt_now - dt.datetime.strptime(job.context["dt_start"], '%Y-%m-%d %H:%M:%S'))
elapsed = dt.timedelta(delta_dt.total_seconds())
answer = '{0} were elapsed!*'.format(elapsed)
text_message = "You had pressed the button at *{0}*.\nAfter waiting I sent it at *{1}*".format(
job.context["dt_start"],
dt_now_str)
context.bot.send_message(job.context["chat_id"], text=answer, parse_mode=ParseMode.MARKDOWN)
context.bot.send_message(job.context["chat_id"], text=text_message, parse_mode=ParseMode.MARKDOWN)
def button(update: Update, context: CallbackContext) -> None:
"""Parses the CallbackQuery and updates the message text."""
query = update.callback_query
query.answer()
data = query.data
query.message.reply_text("You selected *" + data + "* option!", parse_mode=ParseMode.MARKDOWN)
dt_start = dt.datetime.now()
chat_id = query.message.chat_id
payload = {"chat_id": chat_id, "dt_start": dt.datetime.strftime(dt_start, '%Y-%m-%d %H:%M:%S')}
if data == '15m':
context.job_queue.run_once(alarm, t.DURATION_15M, context=payload, name=str(chat_id))
if data == '4h':
context.job_queue.run_once(alarm, t.DURATION_4H, context=payload, name=str(chat_id))
if __name__ == '__main__':
"""Run bot."""
defaults = Defaults(parse_mode=ParseMode.HTML, tzinfo=pytz.timezone('Europe/Moscow'),)
updater = Updater(t.TOKEN, request_kwargs={'read_timeout': 4*3600, 'connect_timeout': 4*3600})
updater.dispatcher.add_handler(CommandHandler("start", start))
updater.dispatcher.add_handler(CallbackQueryHandler(button))
# Start the Bot
updater.start_polling(timeout=4*3600)
updater.idle()
telegram_bot_config.py
# -*- coding: utf-8 -*-
TOKEN = "YOUR TOKEN HERE!"
DURATION_15M = 60*15
DURATION_4H = 60*60*4
BUTTON_LABEL1 = "15m"
BUTTON_LABEL2 = "4h"
等待消息15分钟后,每次都会发生错误:
C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\Scripts\python.exe C:/Users/test/Dropbox/Development/TelegramTimerBot/test4.py
2021-07-01 22:43:37,315 - apscheduler.scheduler - INFO - Scheduler started
2021-07-01 22:43:43,133 - apscheduler.scheduler - INFO - Added job "1234567" to job store "default"
2021-07-01 22:58:43,098 - apscheduler.executors.default - INFO - Running job "1234567 (trigger: date[2021-07-01 19:58:43 UTC], next run at: 2021-07-01 19:58:43 UTC)" (scheduled at 2021-07-01 19:58:43.092836+00:00)
2021-07-01 22:58:43,099 - apscheduler.scheduler - INFO - Removed job 8ed316fd7340464b948d0f41bce318de
2021-07-01 22:58:43,105 - telegram.ext.dispatcher - ERROR - No error handlers are registered, logging exception.
Traceback (most recent call last):
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 617, in urlopen
chunked=chunked)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 402, in _make_request
six.raise_from(e, None)
File "<string>", line 2, in raise_from
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 398, in _make_request
httplib_response = conn.getresponse()
File "C:\Python37\lib\http\client.py", line 1344, in getresponse
response.begin()
File "C:\Python37\lib\http\client.py", line 306, in begin
version, status, reason = self._read_status()
File "C:\Python37\lib\http\client.py", line 275, in _read_status
raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\utils\request.py", line 259, in _request_wrapper
resp = self._con_pool.request(*args, **kwargs)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\request.py", line 70, in request
**urlopen_kw)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\request.py", line 148, in request_encode_body
return self.urlopen(method, url, **extra_kw)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\poolmanager.py", line 244, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 666, in urlopen
_stacktrace=sys.exc_info()[2])
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\util\retry.py", line 347, in increment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\packages\six.py", line 685, in reraise
raise value.with_traceback(tb)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 617, in urlopen
chunked=chunked)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 402, in _make_request
six.raise_from(e, None)
File "<string>", line 2, in raise_from
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 398, in _make_request
httplib_response = conn.getresponse()
File "C:\Python37\lib\http\client.py", line 1344, in getresponse
response.begin()
File "C:\Python37\lib\http\client.py", line 306, in begin
version, status, reason = self._read_status()
File "C:\Python37\lib\http\client.py", line 275, in _read_status
raise RemoteDisconnected("Remote end closed connection without"
telegram.vendor.ptb_urllib3.urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job
retval = job.func(*job.args, **job.kwargs)
File "C:/Users/test/Dropbox/Development/TelegramTimerBot/test4.py", line 52, in alarm
context.bot.send_message(job.context["chat_id"], text=text_message, parse_mode=ParseMode.MARKDOWN)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\bot.py", line 129, in decorator
result = func(*args, **kwargs)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\bot.py", line 507, in send_message
api_kwargs=api_kwargs,
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\ext\extbot.py", line 206, in _message
api_kwargs=api_kwargs,
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\bot.py", line 331, in _message
result = self._post(endpoint, data, timeout=timeout, api_kwargs=api_kwargs)
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\bot.py", line 295, in _post
f'{self.base_url}/{endpoint}', data=data, timeout=effective_timeout
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\utils\request.py", line 361, in post
**urlopen_kwargs,
File "C:\Users\test\Dropbox\Development\TelegramTimerBot\venv\lib\site-packages\telegram\utils\request.py", line 265, in _request_wrapper
raise NetworkError(f'urllib3 HTTPError {error}') from error
telegram.error.NetworkError: urllib3 HTTPError ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
IISC
RemoteDisconnected('Remote end closed connection without response')
表示电报关闭了连接,也就是说,这不是您/ptbs方面的问题。让我有点吃惊的是-如果我理解正确的话-alarm
中的第二个send_message
请求中,而不发生在第一个请求中你能确认以上所有内容吗?当您更改间隔或甚至直接在
alarm
内运行代码(而不是安排作业)时,是否会出现相同的问题我建议还可以查看一下network errors上的ptbs wiki页面
免责声明:我目前是
python-telegram-bot
的维护者Edit
我试图复制,但没有得到任何例外。我使用的是最新版本的PTB(实际上,在
master
分支上…),并且在Windows下使用py3.7。此外,我还对您的示例进行了一些压缩,因此为了完整性起见,这里是我使用的mwe:相关问题 更多 >
编程相关推荐