У меня был один и тот же вопрос, как ОП, и пытались каждый и каждое решение я смог найти в Интернете ... Ну, ни один из них не работал в моей истинной удовлетворенности, так что я имею выбрал исследование, чтобы найти надежный и отзывчивый способ проверки наличия соединения с сервером базы данных MongoDB. И это не блокировать синхронное выполнение приложения слишком длительного периода времени ...
Так вот мои предпосылки:
- Синхронная обработка соединения проверить
- Короткое замыкание на очень короткий временной отрезок для подключение проверка
- Надежность соединения проверить
- Если возможно, не бросать исключения и не запускающие таймауты
Я предоставил новую установку MongoDB (версия 3.6) по адресу localhost по умолчанию: mongodb: // localhost: 27017. Я также записал еще один URL-адрес, где не было сервера базы данных MongoDB: mongodb: // localhost: 27071.
Я также использую C# Driver 2.4.4 и do не использовать устаревшую реализацию (MongoDB.Driver.Legacy assembly).
Итак, мои ожидания состоят в том, что когда я проверяю подключение к первому URL-адресу, он должен предоставить мне Ok для живого соединения с существующим сервером MongoDB, когда я проверяю соединение со вторым URL-адресом. должен предоставить мне Fail для несуществующего сервера MongoDB ...
Использование метода IMongoDatabase.RunCommand запрашивает сервер и заставляет тайм-аут ответа сервера истекать, тем самым не отступая от предпосылок.Кроме того, после таймаута он прерывается с TimeoutException, что требует дополнительной обработки исключений.
Настоящий вопрос SO, а также this Вопрос SO доставил большую часть информации о начале работы, которая мне нужна для моего решения ... Итак, ребята, большое спасибо за это!
Теперь мое решение:
private static bool ProbeForMongoDbConnection(string connectionString, string dbName)
{
var probeTask =
Task.Run(() =>
{
var isAlive = false;
var client = new MongoDB.Driver.MongoClient(connectionString);
for (var k = 0; k < 6; k++)
{
client.GetDatabase(dbName);
var server = client.Cluster.Description.Servers.FirstOrDefault();
isAlive = (server != null &&
server.HeartbeatException == null &&
server.State == MongoDB.Driver.Core.Servers.ServerState.Connected);
if (isAlive)
{
break;
}
System.Threading.Thread.Sleep(300);
}
return isAlive;
});
probeTask.Wait();
return probeTask.Result;
}
Идея это MongoDB сервер не реагирует (и, кажется, не существует), пока реальная попытка не сделана, чтобы получить доступ к некоторому ресурсу на сервере (для пример базы данных). Но получить один ресурс в одиночку недостаточно, так как сервер по-прежнему не имеет обновлений своего состояния в описании кластера сервера. Это обновление происходит во-первых, когда ресурс снова извлекается. С этого момента сервер имеет действительное описание кластера и действительные данные внутри него ...
Как мне кажется, сервер MongoDB не распространяет свое описание кластера всем подключенным клиентам. Вместо этого каждый клиент получает описание, когда был сделан запрос на сервер. Если у некоторых из вас есть более подробная информация об этом, пожалуйста, подтвердите или отклоните мое понимание по теме ...
Теперь, когда мы нацеливаем неверный URL-адрес сервера MongoDB, описание кластера остается недействительным, и мы можем поймать и доставить пригодный для использования сигнала для этого случая ...
Так следующие утверждения (для действительного URL)
// The admin database should exist on each MongoDB 3.6 Installation, if not explicitly deleted!
var isAlive = ProbeForMongoDbConnection("mongodb://localhost:27017", "admin");
Console.WriteLine("Connection to mongodb://localhost:27017 was " + (isAlive ? "successful!" : "NOT successful!"));
напечатает
подключения к MongoDB: // лок lhost: 27017 был успешным!
и заявления (для недействительного URL)
// The admin database should exist on each MongoDB 3.6 Installation, if not explicitly deleted!
isAlive = ProbeForMongoDbConnection("mongodb://localhost:27071", "admin");
Console.WriteLine("Connection to mongodb://localhost:27071 was " + (isAlive ? "successful!" : "NOT successful!"));
напечатает
подключения к MongoDB: // локальный: 27071 НЕ был успешным!
Документация по API на этом слабая, очень слабая, но обычно известный протокол - это исключение, если вы не можете делать что-то вроде GetServer или GetDatabase. Я бы поставил попытку поймать эти утверждения, и если вы не увидите, что Exception просто продолжите. Исключение покажет вам, что вам нужно знать. –
Вот и все. Но проблема в том, что «try-catch» не помогает в этом случае. – Jacobian
Честно говоря, 'try-catch' помогает, но частично. Это connectionString «mongo: // localhost» приводит к ошибке, но этот «mongodb: // 123» - нет. – Jacobian