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()
|
||||
{
|
||||
Td.Client result = Td.Client.Create(new UpdateHandler());
|
||||
new Thread(() =>
|
||||
{
|
||||
Thread.CurrentThread.IsBackground = true;
|
||||
result.Run();
|
||||
}).Start();
|
||||
return result;
|
||||
return Td.Client.Create(new UpdateHandler());
|
||||
}
|
||||
|
||||
private static void Print(string str)
|
||||
@ -133,7 +127,6 @@ namespace TdExample
|
||||
else if (_authorizationState is TdApi.AuthorizationStateClosed)
|
||||
{
|
||||
Print("Closed");
|
||||
_client.Dispose(); // _client is closed and native resources can be disposed now
|
||||
if (!_needQuit)
|
||||
{
|
||||
_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");
|
||||
}
|
||||
new Thread(() =>
|
||||
{
|
||||
Thread.CurrentThread.IsBackground = true;
|
||||
Td.Client.Run();
|
||||
}).Start();
|
||||
|
||||
// create Td.Client
|
||||
_client = CreateTdClient();
|
||||
|
@ -30,11 +30,11 @@ namespace TdApp
|
||||
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.SetLogMessageCallback(100, LogMessageCallback);
|
||||
|
||||
System.Threading.Tasks.Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Td.Client.Run();
|
||||
});
|
||||
|
||||
_client = Td.Client.Create(_handler);
|
||||
var parameters = new TdApi.TdlibParameters();
|
||||
parameters.DatabaseDirectory = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
|
||||
@ -47,13 +47,6 @@ namespace TdApp
|
||||
parameters.ApplicationVersion = "1.0.0";
|
||||
_client.Send(new TdApi.SetTdlibParameters(parameters), null);
|
||||
_client.Send(new TdApi.CheckDatabaseEncryptionKey(), null);
|
||||
_client.Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Print(ex.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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>
|
||||
/// <exception cref="NullReferenceException">Thrown when query is null.</exception>
|
||||
void Send(Api::Function^ function, ClientResultHandler^ handler) {
|
||||
if (function == nullptr) {
|
||||
throw REF_NEW NullReferenceException("Function can't be null");
|
||||
}
|
||||
|
||||
std::uint64_t queryId = Increment(currentId);
|
||||
std::uint64_t requestId = Increment(currentRequestId);
|
||||
if (handler != nullptr) {
|
||||
handlers[queryId] = handler;
|
||||
handlers[requestId] = handler;
|
||||
}
|
||||
td::Client::Request request;
|
||||
request.id = queryId;
|
||||
request.function = td::td_api::move_object_as<td::td_api::Function>(ToUnmanaged(function)->get_object_ptr());
|
||||
client->send(std::move(request));
|
||||
auto request = td::td_api::move_object_as<td::td_api::Function>(ToUnmanaged(function)->get_object_ptr());
|
||||
td::ClientManager::get_manager_singleton()->send(clientId, requestId, std::move(request));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -77,31 +71,32 @@ public:
|
||||
/// <returns>Returns request result.</returns>
|
||||
/// <exception cref="NullReferenceException">Thrown when query is null.</exception>
|
||||
static Api::BaseObject^ Execute(Api::Function^ function) {
|
||||
if (function == nullptr) {
|
||||
throw REF_NEW NullReferenceException("Function can't be null");
|
||||
}
|
||||
|
||||
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);
|
||||
auto request = td::td_api::move_object_as<td::td_api::Function>(ToUnmanaged(function)->get_object_ptr());
|
||||
return Api::FromUnmanaged(*td::ClientManager::execute(std::move(request)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// Returns only when TDLib instance is closed.
|
||||
/// Must be called once on a separate dedicated thread, on which all updates and query results from all Clients will be handled.
|
||||
/// Never returns.
|
||||
/// </summary>
|
||||
void Run() {
|
||||
static void Run() {
|
||||
while (true) {
|
||||
auto response = client->receive(10.0);
|
||||
auto response = td::ClientManager::get_manager_singleton()->receive(300.0);
|
||||
if (response.object != nullptr) {
|
||||
ProcessResult(response.id, Api::FromUnmanaged(*response.object));
|
||||
|
||||
if (response.object->get_id() == td::td_api::updateAuthorizationState::ID &&
|
||||
bool isClosed = response.object->get_id() == td::td_api::updateAuthorizationState::ID &&
|
||||
static_cast<td::td_api::updateAuthorizationState &>(*response.object).authorization_state_->get_id() ==
|
||||
td::td_api::authorizationStateClosed::ID) {
|
||||
break;
|
||||
td::td_api::authorizationStateClosed::ID && response.request_id == 0;
|
||||
|
||||
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) {
|
||||
std::lock_guard<std::mutex> lock(logMutex);
|
||||
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;
|
||||
} else {
|
||||
logMessageCallback = callback;
|
||||
::td::ClientManager::set_log_message_callback(max_verbosity_level, LogMessageCallbackWrapper);
|
||||
td::ClientManager::set_log_message_callback(max_verbosity_level, LogMessageCallbackWrapper);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
Client(ClientResultHandler^ updateHandler) {
|
||||
client = new td::Client();
|
||||
handlers[0] = updateHandler;
|
||||
clientId = td::ClientManager::get_manager_singleton()->create_client_id();
|
||||
if (updateHandler != nullptr) {
|
||||
updateHandlers[clientId] = updateHandler;
|
||||
}
|
||||
Send(REF_NEW Api::GetOption("version"), nullptr);
|
||||
}
|
||||
|
||||
~Client() {
|
||||
delete client;
|
||||
}
|
||||
|
||||
std::int64_t currentId = 0;
|
||||
ConcurrentDictionary<std::uint64_t, ClientResultHandler^> handlers;
|
||||
td::Client *client = nullptr;
|
||||
|
||||
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
|
||||
static std::int64_t currentRequestId;
|
||||
#else
|
||||
static std::int64_t currentRequestId = 0;
|
||||
#endif
|
||||
static ConcurrentDictionary<std::uint64_t, ClientResultHandler^> handlers;
|
||||
static ConcurrentDictionary<std::int32_t, ClientResultHandler^> updateHandlers;
|
||||
std::int32_t clientId;
|
||||
|
||||
#if !TD_CLI
|
||||
static std::mutex logMutex;
|
||||
@ -173,6 +163,10 @@ private:
|
||||
};
|
||||
|
||||
#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;
|
||||
LogMessageCallback^ Client::logMessageCallback;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user