Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TLSharp error when uploading several files

I'm using TLSharp. My goal is to send files to the user. I created ASP.NET Core Web API service and make HTTP request when I need to send file.

It works well with one file but every time when I get 2 or more requests in a short period of time I get an error:

System.InvalidOperationException: invalid checksum! skip.

Controller:

[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();
}

SendFileToBot method:

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);
}

When the requests are sent together (or in short period of time), they're sent in a single packet to Telegram server and this error occurs. I need help with this error. I've tried to use Task.Delay but it doesn't help.

How can I handle requests to avoid this error?

like image 362
Nikita Avatar asked Feb 24 '20 14:02

Nikita


1 Answers

According this issue, you are not first person who received this error.

Seems like there are something request/response validation issues when using multithreading in TLSharp library.

There is one stable workaround for such type of problems.

Make all upload requests synchronous

Actually, they will be asynchronous, but with one-task-at-one-time access

This dirty but workable solution can be achieved by creating task queue:

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();
        }
    }
}

Now you must register queue as singleton in Startup.cs file to be sure that your asp.net core application using one task queue instance to perform uploading on telegram servers:

public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddSingleton<TaskQueue>();
    //...
}

Next, get your task queue instance in your api controller constructor like:

private readonly TaskQueue taskQueue;

public MyController(TaskQueue taskQueue)
{
    this.taskQueue = taskQueue
}

Then, just use it in all of your api methods:

// Code from your API method...
await taskQueue.Enqueue(() => client.SendUploadedDocument(bot, fileResult, "caption", mime, attr));

This will make all requests to telegram servers through TLSharp library synchronous and prevent multithreading issues like in a question.


To be honest, it's just a workaround, not solution of this problem. I'm sure that this issue on github about checksum error must be investigated more detailed and fixed if it possible.

like image 145
picolino Avatar answered Nov 03 '22 01:11

picolino