Use ClientManager instead of Client in ClientDotNet.
This commit is contained in:
parent
0208b7058b
commit
ad2cc6e534
@ -34,13 +34,7 @@ namespace TdExample
|
|||||||
|
|
||||||
private static Td.Client CreateTdClient()
|
private static Td.Client CreateTdClient()
|
||||||
{
|
{
|
||||||
Td.Client result = Td.Client.Create(new UpdateHandler());
|
return Td.Client.Create(new UpdateHandler());
|
||||||
new Thread(() =>
|
|
||||||
{
|
|
||||||
Thread.CurrentThread.IsBackground = true;
|
|
||||||
result.Run();
|
|
||||||
}).Start();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Print(string str)
|
private static void Print(string str)
|
||||||
@ -133,7 +127,6 @@ namespace TdExample
|
|||||||
else if (_authorizationState is TdApi.AuthorizationStateClosed)
|
else if (_authorizationState is TdApi.AuthorizationStateClosed)
|
||||||
{
|
{
|
||||||
Print("Closed");
|
Print("Closed");
|
||||||
_client.Dispose(); // _client is closed and native resources can be disposed now
|
|
||||||
if (!_needQuit)
|
if (!_needQuit)
|
||||||
{
|
{
|
||||||
_client = CreateTdClient(); // recreate _client after previous has closed
|
_client = CreateTdClient(); // recreate _client after previous has closed
|
||||||
@ -223,6 +216,11 @@ namespace TdExample
|
|||||||
{
|
{
|
||||||
throw new System.IO.IOException("Write access to the current directory is required");
|
throw new System.IO.IOException("Write access to the current directory is required");
|
||||||
}
|
}
|
||||||
|
new Thread(() =>
|
||||||
|
{
|
||||||
|
Thread.CurrentThread.IsBackground = true;
|
||||||
|
Td.Client.Run();
|
||||||
|
}).Start();
|
||||||
|
|
||||||
// create Td.Client
|
// create Td.Client
|
||||||
_client = CreateTdClient();
|
_client = CreateTdClient();
|
||||||
|
@ -30,11 +30,11 @@ namespace TdApp
|
|||||||
Td.Client.Execute(new TdApi.SetLogVerbosityLevel(0));
|
Td.Client.Execute(new TdApi.SetLogVerbosityLevel(0));
|
||||||
Td.Client.Execute(new TdApi.SetLogStream(new TdApi.LogStreamFile(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "log"), 1 << 27, false)));
|
Td.Client.Execute(new TdApi.SetLogStream(new TdApi.LogStreamFile(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "log"), 1 << 27, false)));
|
||||||
Td.Client.SetLogMessageCallback(100, LogMessageCallback);
|
Td.Client.SetLogMessageCallback(100, LogMessageCallback);
|
||||||
|
|
||||||
System.Threading.Tasks.Task.Run(() =>
|
System.Threading.Tasks.Task.Run(() =>
|
||||||
{
|
{
|
||||||
try
|
Td.Client.Run();
|
||||||
{
|
});
|
||||||
|
|
||||||
_client = Td.Client.Create(_handler);
|
_client = Td.Client.Create(_handler);
|
||||||
var parameters = new TdApi.TdlibParameters();
|
var parameters = new TdApi.TdlibParameters();
|
||||||
parameters.DatabaseDirectory = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
|
parameters.DatabaseDirectory = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
|
||||||
@ -47,13 +47,6 @@ namespace TdApp
|
|||||||
parameters.ApplicationVersion = "1.0.0";
|
parameters.ApplicationVersion = "1.0.0";
|
||||||
_client.Send(new TdApi.SetTdlibParameters(parameters), null);
|
_client.Send(new TdApi.SetTdlibParameters(parameters), null);
|
||||||
_client.Send(new TdApi.CheckDatabaseEncryptionKey(), null);
|
_client.Send(new TdApi.CheckDatabaseEncryptionKey(), null);
|
||||||
_client.Run();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Print(ex.ToString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Print(String str)
|
public void Print(String str)
|
||||||
|
@ -56,18 +56,12 @@ public:
|
|||||||
/// of the query or with Telegram.Td.Api.Error as parameter. If it is null, nothing will be called.</param>
|
/// of the query or with Telegram.Td.Api.Error as parameter. If it is null, nothing will be called.</param>
|
||||||
/// <exception cref="NullReferenceException">Thrown when query is null.</exception>
|
/// <exception cref="NullReferenceException">Thrown when query is null.</exception>
|
||||||
void Send(Api::Function^ function, ClientResultHandler^ handler) {
|
void Send(Api::Function^ function, ClientResultHandler^ handler) {
|
||||||
if (function == nullptr) {
|
std::uint64_t requestId = Increment(currentRequestId);
|
||||||
throw REF_NEW NullReferenceException("Function can't be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint64_t queryId = Increment(currentId);
|
|
||||||
if (handler != nullptr) {
|
if (handler != nullptr) {
|
||||||
handlers[queryId] = handler;
|
handlers[requestId] = handler;
|
||||||
}
|
}
|
||||||
td::Client::Request request;
|
auto request = td::td_api::move_object_as<td::td_api::Function>(ToUnmanaged(function)->get_object_ptr());
|
||||||
request.id = queryId;
|
td::ClientManager::get_manager_singleton()->send(clientId, requestId, std::move(request));
|
||||||
request.function = td::td_api::move_object_as<td::td_api::Function>(ToUnmanaged(function)->get_object_ptr());
|
|
||||||
client->send(std::move(request));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -77,31 +71,32 @@ public:
|
|||||||
/// <returns>Returns request result.</returns>
|
/// <returns>Returns request result.</returns>
|
||||||
/// <exception cref="NullReferenceException">Thrown when query is null.</exception>
|
/// <exception cref="NullReferenceException">Thrown when query is null.</exception>
|
||||||
static Api::BaseObject^ Execute(Api::Function^ function) {
|
static Api::BaseObject^ Execute(Api::Function^ function) {
|
||||||
if (function == nullptr) {
|
auto request = td::td_api::move_object_as<td::td_api::Function>(ToUnmanaged(function)->get_object_ptr());
|
||||||
throw REF_NEW NullReferenceException("Function can't be null");
|
return Api::FromUnmanaged(*td::ClientManager::execute(std::move(request)));
|
||||||
}
|
|
||||||
|
|
||||||
td::Client::Request request;
|
|
||||||
request.id = 0;
|
|
||||||
request.function = td::td_api::move_object_as<td::td_api::Function>(ToUnmanaged(function)->get_object_ptr());
|
|
||||||
return Api::FromUnmanaged(*td::Client::execute(std::move(request)).object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Launches a cycle which will fetch all results of queries to TDLib and incoming updates from TDLib.
|
/// Launches a cycle which will fetch all results of queries to TDLib and incoming updates from TDLib.
|
||||||
/// Must be called once on a separate dedicated thread, on which all updates and query results will be handled.
|
/// Must be called once on a separate dedicated thread, on which all updates and query results from all Clients will be handled.
|
||||||
/// Returns only when TDLib instance is closed.
|
/// Never returns.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Run() {
|
static void Run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
auto response = client->receive(10.0);
|
auto response = td::ClientManager::get_manager_singleton()->receive(300.0);
|
||||||
if (response.object != nullptr) {
|
if (response.object != nullptr) {
|
||||||
ProcessResult(response.id, Api::FromUnmanaged(*response.object));
|
bool isClosed = response.object->get_id() == td::td_api::updateAuthorizationState::ID &&
|
||||||
|
|
||||||
if (response.object->get_id() == td::td_api::updateAuthorizationState::ID &&
|
|
||||||
static_cast<td::td_api::updateAuthorizationState &>(*response.object).authorization_state_->get_id() ==
|
static_cast<td::td_api::updateAuthorizationState &>(*response.object).authorization_state_->get_id() ==
|
||||||
td::td_api::authorizationStateClosed::ID) {
|
td::td_api::authorizationStateClosed::ID && response.request_id == 0;
|
||||||
break;
|
|
||||||
|
ClientResultHandler^ handler;
|
||||||
|
if (response.request_id == 0 ? updateHandlers.TryGetValue(response.client_id, handler) :
|
||||||
|
handlers.TryRemove(response.request_id, handler)) {
|
||||||
|
// TODO try/catch
|
||||||
|
handler->OnResult(Api::FromUnmanaged(*response.object));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isClosed) {
|
||||||
|
updateHandlers.TryRemove(response.client_id, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,37 +122,32 @@ public:
|
|||||||
static void SetLogMessageCallback(std::int32_t max_verbosity_level, LogMessageCallback^ callback) {
|
static void SetLogMessageCallback(std::int32_t max_verbosity_level, LogMessageCallback^ callback) {
|
||||||
std::lock_guard<std::mutex> lock(logMutex);
|
std::lock_guard<std::mutex> lock(logMutex);
|
||||||
if (callback == nullptr) {
|
if (callback == nullptr) {
|
||||||
::td::ClientManager::set_log_message_callback(max_verbosity_level, nullptr);
|
td::ClientManager::set_log_message_callback(max_verbosity_level, nullptr);
|
||||||
logMessageCallback = nullptr;
|
logMessageCallback = nullptr;
|
||||||
} else {
|
} else {
|
||||||
logMessageCallback = callback;
|
logMessageCallback = callback;
|
||||||
::td::ClientManager::set_log_message_callback(max_verbosity_level, LogMessageCallbackWrapper);
|
td::ClientManager::set_log_message_callback(max_verbosity_level, LogMessageCallbackWrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Client(ClientResultHandler^ updateHandler) {
|
Client(ClientResultHandler^ updateHandler) {
|
||||||
client = new td::Client();
|
clientId = td::ClientManager::get_manager_singleton()->create_client_id();
|
||||||
handlers[0] = updateHandler;
|
if (updateHandler != nullptr) {
|
||||||
|
updateHandlers[clientId] = updateHandler;
|
||||||
|
}
|
||||||
|
Send(REF_NEW Api::GetOption("version"), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Client() {
|
#if !TD_CLI
|
||||||
delete client;
|
static std::int64_t currentRequestId;
|
||||||
}
|
#else
|
||||||
|
static std::int64_t currentRequestId = 0;
|
||||||
std::int64_t currentId = 0;
|
#endif
|
||||||
ConcurrentDictionary<std::uint64_t, ClientResultHandler^> handlers;
|
static ConcurrentDictionary<std::uint64_t, ClientResultHandler^> handlers;
|
||||||
td::Client *client = nullptr;
|
static ConcurrentDictionary<std::int32_t, ClientResultHandler^> updateHandlers;
|
||||||
|
std::int32_t clientId;
|
||||||
void ProcessResult(std::uint64_t id, Api::BaseObject^ object) {
|
|
||||||
ClientResultHandler^ handler;
|
|
||||||
// update handler stays forever
|
|
||||||
if (id == 0 ? handlers.TryGetValue(id, handler) : handlers.TryRemove(id, handler)) {
|
|
||||||
// TODO try/catch
|
|
||||||
handler->OnResult(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !TD_CLI
|
#if !TD_CLI
|
||||||
static std::mutex logMutex;
|
static std::mutex logMutex;
|
||||||
@ -173,6 +163,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if !TD_CLI
|
#if !TD_CLI
|
||||||
|
std::int64_t Client::currentRequestId = 0;
|
||||||
|
ConcurrentDictionary<std::uint64_t, ClientResultHandler^> Client::handlers;
|
||||||
|
ConcurrentDictionary<std::int32_t, ClientResultHandler^> Client::updateHandlers;
|
||||||
|
|
||||||
std::mutex Client::logMutex;
|
std::mutex Client::logMutex;
|
||||||
LogMessageCallback^ Client::logMessageCallback;
|
LogMessageCallback^ Client::logMessageCallback;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user