基于ASP.NET的C# Telegram Bot无法运行求助(附Application_Start代码)
解决ASP.NET Web应用中Telegram Bot无法运行的问题
看起来你在ASP.NET Web应用里部署Telegram Bot时踩坑了,结合你给出的代码片段,我梳理几个核心问题和对应的修复方案:
1. 选对更新接收方式:Webhook是最优解
传统ASP.NET是请求驱动架构,完全不适合用长轮询——长轮询需要持续运行的线程,但Web应用的线程会在请求结束后释放,还容易被应用池回收打断。Telegram官方明确推荐Web应用使用Webhook来接收更新。
配置Webhook的具体步骤:
- 先创建一个Ashx处理程序作为Webhook的接收端点,比如
WebhookHandler.ashx:
using System.Web; using Telegram.Bot; using Telegram.Bot.Types; namespace MyFirstBot { public class WebhookHandler : IHttpHandler { // 用静态实例保证Bot对象在应用生命周期内持续存在 private static readonly TelegramBotClient _bot = new TelegramBotClient("你的Bot Token"); public void ProcessRequest(HttpContext context) { // 读取Telegram发送的更新数据 var update = _bot.DeserializeUpdate(context.Request.InputStream); // 异步处理更新(这里用Wait是因为Ashx不支持async,若用Web API可直接返回Task) HandleUpdateAsync(update).Wait(); // 返回200状态码告诉Telegram已接收成功 context.Response.StatusCode = 200; } private async System.Threading.Tasks.Task HandleUpdateAsync(Update update) { if (update.Message != null) { // 示例:回复用户发送的内容 await _bot.SendTextMessageAsync( chatId: update.Message.Chat.Id, text: $"你发了:{update.Message.Text}" ); } } public bool IsReusable => true; } }
- 然后在
Application_Start中设置Webhook(注意:你的Web应用必须有公网HTTPS地址,Telegram要求Webhook必须用HTTPS):
protected void Application_Start(object sender, EventArgs e) { var bot = new TelegramBotClient("你的Bot Token"); // 替换成你的Webhook端点的公网HTTPS地址 var webhookUrl = "https://你的域名.com/WebhookHandler.ashx"; // 同步设置Webhook(也可以用async/await,这里用Wait是因为Application_Start不支持异步) bot.SetWebhookAsync(webhookUrl).Wait(); }
2. 规避Bot实例的生命周期问题
你之前在Global.asax里直接实例化TelegramBotClient,但ASP.NET应用池会因为空闲时间过长回收应用,导致Bot实例被销毁。建议:
- 在Webhook处理程序中使用静态的
TelegramBotClient实例(如上面的代码),确保它在应用运行期间不会被随意销毁。 - 可以适当调整应用池的回收设置(比如延长空闲超时时间),但这只是辅助手段,核心还是依赖Webhook的请求驱动模式。
3. 排查常见的坑点
- HTTPS强制要求:Telegram的Webhook只接受HTTPS地址,本地测试可以用ngrok之类的工具把本地HTTP端口映射成公网HTTPS地址。
- Token正确性:确认你的Bot Token是从@BotFather那里获取的正确值,没有拼写错误或者多余空格。
- 端点可访问性:确保Webhook的端点能被公网访问,没有被防火墙、CDN或者服务器安全组拦截。
- Bot权限设置:在@BotFather的Bot设置里检查是否开启了必要的权限(比如发送消息、读取消息的权限)。
如果你非要用长轮询(不推荐生产环境)
如果因为特殊需求必须用长轮询,你需要在ASP.NET中启动一个后台线程来持续拉取更新,但要做好应用池回收的心理准备:
protected void Application_Start(object sender, EventArgs e) { var bot = new TelegramBotClient("你的Bot Token"); // 启动后台线程执行长轮询 System.Threading.Tasks.Task.Run(() => StartLongPolling(bot)); } private async System.Threading.Tasks.Task StartLongPolling(TelegramBotClient bot) { var offset = 0; while (true) { try { var updates = await bot.GetUpdatesAsync(offset); foreach (var update in updates) { if (update.Message != null) { await bot.SendTextMessageAsync(update.Message.Chat.Id, "收到消息啦!"); } offset = update.Id + 1; } // 每秒轮询一次,避免请求过于频繁 await System.Threading.Tasks.Task.Delay(1000); } catch (Exception ex) { // 异常处理:记录日志,避免线程崩溃 await System.Threading.Tasks.Task.Delay(5000); } } }
⚠️ 提醒:这种方式在生产环境极不稳定,应用池一回收,后台线程就会终止,所以强烈优先选择Webhook方案。
内容的提问来源于stack exchange,提问作者MMSH
相关产品推荐
相关产品推荐

