Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed the "File located on a different DC" issue #53

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ TgSharp provides two wrappers for sending photo and document:
await client.SendUploadedDocument(new TLInputPeerUser() { UserId = user.Id },
fileResult,
"application/zip", //mime-type
"kitty", // message text

//document attributes, such as file name
new TLVector<TLAbsDocumentAttribute>());
Expand All @@ -134,6 +135,7 @@ You can see the Full code at [SendPhotoToContactTest](https://github.com/nblockc
To download a file you should call the **GetFile** method:

```csharp
// get documnet
await client.GetFile(new TLInputDocumentFileLocation()
{
AccessHash = document.AccessHash,
Expand All @@ -144,6 +146,18 @@ To download a file you should call the **GetFile** method:

//size of fileChunk you want to retrieve
document.Size);
// get photo
TLPhotoSize photoSize = photo.Sizes.ToList().OfType<TLPhotoSize>().Last();
await client.GetFile(new TLInputPhotoFileLocation()
{
AccessHash = photo.AccessHash,
Id = photo.Id,
FileReference = photo.FileReference,
ThumbSize = photoSize.Type,
},

//size of fileChunk you want to retrieve
photoSize.Size);
```

You can see the Full code at [DownloadFileFromContactTest](https://github.com/nblockchain/TgSharp/blob/master/src/TgSharp.Tests/TgSharpTests.cs#L167)
Expand Down
54 changes: 43 additions & 11 deletions src/TgSharp.Core/TelegramClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class TelegramClient : IDisposable

public Session Session { get; private set; }

private Dictionary<int, Tuple<TLUser, AuthKey, int>> authCache;

/// <summary>
/// Creates a new TelegramClient
/// </summary>
Expand Down Expand Up @@ -68,6 +70,8 @@ public TelegramClient(int apiId, string apiHash,
this.dcIpVersion = dcIpVersion;

this.sessionUserId = sessionUserId;

this.authCache = new Dictionary<int, Tuple<TLUser, AuthKey, int>>();
}

public async Task ConnectAsync (CancellationToken token = default (CancellationToken))
Expand All @@ -79,7 +83,9 @@ public TelegramClient(int apiId, string apiHash,
{
token.ThrowIfCancellationRequested();

Session = SessionFactory.TryLoadOrCreateNew (store, sessionUserId);
if (Session == null) {
Session = SessionFactory.TryLoadOrCreateNew (store, sessionUserId);
}
transport = new TcpTransport (Session.DataCenter.Address, Session.DataCenter.Port, this.handler);

if (Session.AuthKey == null || reconnect)
Expand Down Expand Up @@ -109,6 +115,15 @@ public TelegramClient(int apiId, string apiHash,
await sender.Receive(invokewithLayer, token).ConfigureAwait(false);

dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList();

// determine the current dc id
if (Session.DataCenter.DataCenterId == null) {
var currDc = dcOptions.FirstOrDefault(d => d.IpAddress == Session.DataCenter.Address && d.Port == Session.DataCenter.Port);
if (currDc != null) {
Session.DataCenter = new DataCenter(currDc.Id, Session.DataCenter.Address, Session.DataCenter.Port);
this.store.Save(Session);
}
}
}

private async Task ReconnectToDcAsync(int dcId, CancellationToken token = default(CancellationToken))
Expand All @@ -118,8 +133,15 @@ public TelegramClient(int apiId, string apiHash,
if (dcOptions == null || !dcOptions.Any())
throw new InvalidOperationException($"Can't reconnect. Establish initial connection first.");

// cache the current auth
if (Session.DataCenter.DataCenterId.HasValue) {
authCache[Session.DataCenter.DataCenterId.Value] =
new Tuple<TLUser, AuthKey, int>(Session.TLUser, Session.AuthKey, Session.TimeOffset);
}

// export auth only if there is no cached one
TLExportedAuthorization exported = null;
if (Session.TLUser != null)
if (Session.TLUser != null && !authCache.ContainsKey(dcId))
{
TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId };
exported = await SendRequestAsync<TLExportedAuthorization>(exportAuthorization, token).ConfigureAwait(false);
Expand Down Expand Up @@ -148,15 +170,24 @@ public TelegramClient(int apiId, string apiHash,

var dataCenter = new DataCenter (dcId, dc.IpAddress, dc.Port);
Session.DataCenter = dataCenter;
this.store.Save (Session);

await ConnectInternalAsync(true, token).ConfigureAwait(false);

if (Session.TLUser != null)
{
TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes };
var imported = await SendRequestAsync<TLAuthorization>(importAuthorization, token).ConfigureAwait(false);
OnUserAuthenticated((TLUser)imported.User);
Tuple<TLUser, AuthKey, int> cachedAuth;
if (authCache.TryGetValue(dcId, out cachedAuth)) {
// use cached auth if exists
Session.AuthKey = cachedAuth.Item2;
Session.TimeOffset = cachedAuth.Item3;
await ConnectInternalAsync(false, token).ConfigureAwait(false);
OnUserAuthenticated(cachedAuth.Item1);

} else {
await ConnectInternalAsync(true, token).ConfigureAwait(false);

// otherwise import the previously exported auth
if (Session.TLUser != null) {
TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes };
var imported = await SendRequestAsync<TLAuthorization>(importAuthorization, token).ConfigureAwait(false);
OnUserAuthenticated((TLUser)imported.User);
}
}
}

Expand Down Expand Up @@ -351,7 +382,7 @@ public bool IsUserAuthorized()
}

public async Task<TLAbsUpdates> SendUploadedDocument(
TLAbsInputPeer peer, TLAbsInputFile file, string mimeType, TLVector<TLAbsDocumentAttribute> attributes, CancellationToken token = default(CancellationToken))
TLAbsInputPeer peer, TLAbsInputFile file, string message, string mimeType, TLVector<TLAbsDocumentAttribute> attributes, CancellationToken token = default(CancellationToken))
{
return await SendAuthenticatedRequestAsync<TLAbsUpdates>(new TLRequestSendMedia()
{
Expand All @@ -364,6 +395,7 @@ public async Task<TLAbsUpdates> SendUploadedDocument(
MimeType = mimeType,
Attributes = attributes
},
Message = message,
Peer = peer
}, token)
.ConfigureAwait(false);
Expand Down
1 change: 1 addition & 0 deletions src/TgSharp.Tests/TgSharpTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ public virtual async Task SendBigFileToContactTest()
await client.SendUploadedDocument(
new TLInputPeerUser() { UserId = user.Id },
fileResult,
"some file",
"application/zip",
new TLVector<TLAbsDocumentAttribute>());
}
Expand Down