Core: refactor around Session vs SessionStore

This will help implementing session storage in JSON
format. WIP PRs:
- https://github.com/nblockchain/TgSharp/pull/18
- https://github.com/nblockchain/TgSharp/pull/29
This commit is contained in:
Andres G. Aragoneses 2020-09-15 00:54:43 +08:00
parent 5ae1024eac
commit ef89274e1f
4 changed files with 52 additions and 57 deletions

View file

@ -2,14 +2,17 @@ namespace TgSharp.Core
{
internal class DataCenter
{
internal DataCenter (int? dcId, string address, int port)
private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50";
private const int defaultConnectionPort = 443;
internal DataCenter (int? dcId, string address = defaultConnectionAddress, int port = defaultConnectionPort)
{
DataCenterId = dcId;
Address = address;
Port = port;
}
internal DataCenter (string address, int port) : this (null, address, port)
internal DataCenter (string address = defaultConnectionAddress, int port = defaultConnectionPort) : this (null, address, port)
{
}

View file

@ -23,13 +23,15 @@ namespace TgSharp.Core.Network
//private ulong sessionId = GenerateRandomUlong();
private readonly TcpTransport transport;
private readonly ISessionStore sessionStore;
private readonly Session session;
public readonly List<ulong> needConfirmation = new List<ulong>();
public MtProtoSender(TcpTransport transport, Session session)
public MtProtoSender(TcpTransport transport, ISessionStore sessionStore, Session session)
{
this.transport = transport;
this.sessionStore = sessionStore;
this.session = session;
}
@ -63,7 +65,7 @@ namespace TgSharp.Core.Network
await Send(memory.ToArray(), request, token).ConfigureAwait(false);
}
session.Save();
sessionStore.Save (session);
}
public async Task Send(byte[] packet, TLMethod request, CancellationToken token = default(CancellationToken))

View file

@ -71,11 +71,32 @@ namespace TgSharp.Core
}
}
internal static class SessionFactory
{
internal static Session TryLoadOrCreateNew (ISessionStore store, string sessionUserId)
{
var session = store.Load (sessionUserId);
if (null == session) {
var defaultDataCenter = new DataCenter ();
session = new Session {
Id = GenerateRandomUlong (),
SessionUserId = sessionUserId,
DataCenter = defaultDataCenter,
};
}
return session;
}
private static ulong GenerateRandomUlong ()
{
var random = new Random ();
ulong rand = (((ulong)random.Next ()) << 32) | ((ulong)random.Next ());
return rand;
}
}
public class Session
{
private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50";
private const int defaultConnectionPort = 443;
public int Sequence { get; set; }
#if CI
// see the same CI-wrapped assignment in .FromBytes(), but this one will become useful
@ -100,12 +121,9 @@ namespace TgSharp.Core
public TLUser TLUser { get; set; }
private Random random;
private ISessionStore store;
public Session(ISessionStore store)
public Session()
{
random = new Random();
this.store = store;
}
public byte[] ToBytes()
@ -170,7 +188,7 @@ namespace TgSharp.Core
var authData = Serializers.Bytes.Read(reader);
var defaultDataCenter = new DataCenter (serverAddress, port);
return new Session(store)
return new Session()
{
AuthKey = new AuthKey(authData),
Id = id,
@ -186,30 +204,6 @@ namespace TgSharp.Core
}
}
public void Save()
{
store.Save(this);
}
public static Session TryLoadOrCreateNew(ISessionStore store, string sessionUserId)
{
var defaultDataCenter = new DataCenter (defaultConnectionAddress, defaultConnectionPort);
return store.Load(sessionUserId) ?? new Session(store)
{
Id = GenerateRandomUlong(),
SessionUserId = sessionUserId,
DataCenter = defaultDataCenter,
};
}
private static ulong GenerateRandomUlong()
{
var random = new Random();
ulong rand = (((ulong)random.Next()) << 32) | ((ulong)random.Next());
return rand;
}
public long GetNewMessageId()
{
long time = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds);

View file

@ -31,15 +31,11 @@ namespace TgSharp.Core
private readonly int apiId;
private readonly string sessionUserId;
private readonly ISessionStore store;
private Session session;
private List<TLDcOption> dcOptions;
private readonly TcpClientConnectionHandler handler;
private readonly DataCenterIPVersion dcIpVersion;
public Session Session
{
get { return session; }
}
public Session Session { get; private set; }
/// <summary>
/// Creates a new TelegramClient
@ -83,17 +79,17 @@ namespace TgSharp.Core
{
token.ThrowIfCancellationRequested();
session = Session.TryLoadOrCreateNew (store, sessionUserId);
transport = new TcpTransport (session.DataCenter.Address, session.DataCenter.Port, this.handler);
Session = SessionFactory.TryLoadOrCreateNew (store, sessionUserId);
transport = new TcpTransport (Session.DataCenter.Address, Session.DataCenter.Port, this.handler);
if (session.AuthKey == null || reconnect)
if (Session.AuthKey == null || reconnect)
{
var result = await Authenticator.DoAuthentication(transport, token).ConfigureAwait(false);
session.AuthKey = result.AuthKey;
session.TimeOffset = result.TimeOffset;
Session.AuthKey = result.AuthKey;
Session.TimeOffset = result.TimeOffset;
}
sender = new MtProtoSender(transport, session);
sender = new MtProtoSender(transport, store, Session);
//set-up layer
var config = new TLRequestGetConfig();
@ -123,7 +119,7 @@ namespace TgSharp.Core
throw new InvalidOperationException($"Can't reconnect. Establish initial connection first.");
TLExportedAuthorization exported = null;
if (session.TLUser != null)
if (Session.TLUser != null)
{
TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId };
exported = await SendRequestAsync<TLExportedAuthorization>(exportAuthorization, token).ConfigureAwait(false);
@ -151,12 +147,12 @@ namespace TgSharp.Core
dc = dcs.First();
var dataCenter = new DataCenter (dcId, dc.IpAddress, dc.Port);
session.DataCenter = dataCenter;
session.Save();
Session.DataCenter = dataCenter;
this.store.Save (Session);
await ConnectInternalAsync(true, token).ConfigureAwait(false);
if (session.TLUser != null)
if (Session.TLUser != null)
{
TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes };
var imported = await SendRequestAsync<TLAuthorization>(importAuthorization, token).ConfigureAwait(false);
@ -180,8 +176,8 @@ namespace TgSharp.Core
}
catch (DataCenterMigrationException e)
{
if (session.DataCenter.DataCenterId.HasValue &&
session.DataCenter.DataCenterId.Value == e.DC)
if (Session.DataCenter.DataCenterId.HasValue &&
Session.DataCenter.DataCenterId.Value == e.DC)
{
throw new Exception($"Telegram server replied requesting a migration to DataCenter {e.DC} when this connection was already using this DataCenter", e);
}
@ -195,7 +191,7 @@ namespace TgSharp.Core
public bool IsUserAuthorized()
{
return session.TLUser != null;
return Session.TLUser != null;
}
public async Task<string> SendCodeRequestAsync(string phoneNumber, CancellationToken token = default(CancellationToken))
@ -427,10 +423,10 @@ namespace TgSharp.Core
private void OnUserAuthenticated(TLUser TLUser)
{
session.TLUser = TLUser;
session.SessionExpires = int.MaxValue;
Session.TLUser = TLUser;
Session.SessionExpires = int.MaxValue;
session.Save();
this.store.Save (Session);
}
public bool IsConnected