Nik*_*ita 7 c# telegram asp.net-core
我正在使用 TLSharp。我的目标是将文件发送给用户。我创建了 ASP.NET Core Web API 服务并在需要发送文件时发出 HTTP 请求。
它适用于一个文件,但每次当我在短时间内收到 2 个或更多请求时,我都会收到错误消息:
System.InvalidOperationException:校验和无效!跳过。
控制器:
[Route("upload/{driveId}")]
public async Task<ActionResult> Upload(string driveId)
{
var ms = new MemoryStream();
var file = service.Files.Get(driveId);
string filename = file.Execute().Name;
await file.DownloadAsync(ms);
ms.Position = 0;
new FileExtensionContentTypeProvider().TryGetContentType(filename, out var mime);
var stream = new StreamReader(ms, true);
await _client.SendFileToBot(filename, mime, stream, driveId);
return Ok();
}
Run Code Online (Sandbox Code Playgroud)
SendFileToBot 方法:
public async Task SendFileToBot(string filename, string mime, StreamReader stream)
{
var found = await client.SearchUserAsync("username", 1);
//find user
var userToSend = found.Users
.Where(x => x.GetType() == typeof(TLUser))
.Cast<TLUser>()
.FirstOrDefault(x => x.Id == 1234567);
var fileResult = await client.UploadFile(filename, stream);
var attr = new TLVector<TLAbsDocumentAttribute>()
{
new TLDocumentAttributeFilename { FileName = filename }
};
var bot = new TLInputPeerUser() { UserId = userToSend.Id, AccessHash = userToSend.AccessHash.Value };
await client.SendUploadedDocument(bot, fileResult, "caption", mime, attr);
}
Run Code Online (Sandbox Code Playgroud)
当请求一起发送时(或在短时间内),它们以单个数据包的形式发送到 Telegram 服务器并发生此错误。我需要有关此错误的帮助。我试过使用 Task.Delay 但它没有帮助。
如何处理请求以避免此错误?
根据这个问题,您不是第一个收到此错误的人。
在 TLSharp 库中使用多线程时,似乎存在一些请求/响应验证问题。
对于此类问题有一种稳定的解决方法。
实际上,它们将是异步的,但一次只能访问一个任务
这个肮脏但可行的解决方案可以通过创建任务队列来实现:
public class TaskQueue
{
private readonly SemaphoreSlim _semaphoreSlim;
public TaskQueue()
{
_semaphoreSlim = new SemaphoreSlim(1, 1); // Max threads limited to 1.
}
public async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)
{
await _semaphoreSlim.WaitAsync();
try
{
return await taskGenerator();
}
finally
{
_semaphoreSlim.Release();
}
}
public async Task Enqueue(Func<Task> taskGenerator)
{
await _semaphoreSlim.WaitAsync();
try
{
await taskGenerator();
}
finally
{
_semaphoreSlim.Release();
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您必须在文件中将队列注册为单例Startup.cs,以确保您的 ASP.NET Core 应用程序使用一个任务队列实例在 Telegram 服务器上执行上传:
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddSingleton<TaskQueue>();
//...
}
Run Code Online (Sandbox Code Playgroud)
接下来,在 api 控制器构造函数中获取任务队列实例,如下所示:
private readonly TaskQueue taskQueue;
public MyController(TaskQueue taskQueue)
{
this.taskQueue = taskQueue
}
Run Code Online (Sandbox Code Playgroud)
然后,只需在所有 api 方法中使用它即可:
// Code from your API method...
await taskQueue.Enqueue(() => client.SendUploadedDocument(bot, fileResult, "caption", mime, attr));
Run Code Online (Sandbox Code Playgroud)
这将使通过 TLSharp 库向电报服务器发出的所有请求同步,并防止出现问题中的多线程问题。
老实说,这只是一个解决方法,而不是解决这个问题。我确信github 上关于校验和错误的问题必须进行更详细的调查,并在可能的情况下进行修复。
| 归档时间: |
|
| 查看次数: |
368 次 |
| 最近记录: |