2015-03-03 5 views
15

Для подключения к базе данных я использую драйверы MongoDB. Когда моя форма загружается, я хочу настроить соединение и проверить, нормально оно или нет. Я делаю это вот так:Как проверить подключение к mongodb

var connectionString = "mongodb://localhost"; 
var client = new MongoClient(connectionString); 
var server = client.GetServer(); 
var database = server.GetDatabase("reestr"); 

Но я не знаю, как проверить соединение. Я пытался совместить этот код с try-catch, но безрезультатно. Даже если я создаю неверный connectionString, я все равно не могу получить сообщение об ошибке.

+0

Документация по API на этом слабая, очень слабая, но обычно известный протокол - это исключение, если вы не можете делать что-то вроде GetServer или GetDatabase. Я бы поставил попытку поймать эти утверждения, и если вы не увидите, что Exception просто продолжите. Исключение покажет вам, что вам нужно знать. –

+0

Вот и все. Но проблема в том, что «try-catch» не помогает в этом случае. – Jacobian

+0

Честно говоря, 'try-catch' помогает, но частично. Это connectionString «mongo: // localhost» приводит к ошибке, но этот «mongodb: // 123» - нет. – Jacobian

ответ

16

Там в ping method для этого:

var connectionString = "mongodb://localhost"; 
var client = new MongoClient(connectionString); 
var server = client.GetServer(); 
server.Ping(); 
+13

Как вы это сделаете с новым драйвером Mongo DB C# 2.0? – RPDeshaies

+4

Да, любая идея, как проверить статус подключения с новым драйвером 3.0? Он не имеет серверного объекта. –

21

Чтобы пинговать сервер с новым драйвером 3.0 его:

var database = client.GetDatabase("YourDbHere"); 

database.RunCommandAsync((Command<BsonDocument>)"{ping:1}") 
     .Wait(); 
+0

Это асинхронный процесс, есть ли способ синхронизации? –

+2

Начиная с версии 2.0, драйвер только асинхронный. Извините за nitpick, но мой пример на самом деле был синхронным, так как я вызываю 'Wait()' –

+0

. Теперь есть метод RunCommand(). –

0

Если вы хотите, чтобы решать вопросы подключения в вашей программе вы можете использовать ICluster.Description мероприятие.

Когда создается MongoClient, он будет продолжать попытки подключения в фоновом режиме до тех пор, пока он не удастся.

using MongoDB.Driver; 
using MongoDB.Driver.Core.Clusters; 

var mongoClient = new MongoClient("localhost") 
mongoClient.Cluster.DescriptionChanged += Cluster_DescriptionChanged; 

public void Cluster_DescriptionChanged(object sender, ClusterDescriptionChangedEventArgs e) 
{ 
    switch (e.NewClusterDescription.State) 
    { 
     case ClusterState.Disconnected: 
      break; 
     case ClusterState.Connected: 
      break; 
    } 
} 
+0

Это не работает, если вы не сделаете запрос к базе данных после запуска этого кода. Может давать ложные негативы. –

3

полный пример для 2.4.3 - где «client.GetServer()» недоступен. на основе ответа «Пол Кейстер».

client = new MongoClient("mongodb://localhost"); 
database = client.GetDatabase(mongoDbStr); 
bool isMongoLive = database.RunCommandAsync((Command<BsonDocument>)"{ping:1}").Wait(1000); 

if(isMongoLive) 
{ 
    // connected 
} 
else 
{ 
    // couldn't connect 
} 
+0

Как ваш ответ отличается от одного из Пола Кистера? – Jacobian

+2

Непонятно, от ответа Павла, что вы делаете с просьбой. Он указывает в правильном направлении, но не отвечает на вопрос полностью. –

1

У меня был один и тот же вопрос, как ОП, и пытались каждый и каждое решение я смог найти в Интернете ... Ну, ни один из них не работал в моей истинной удовлетворенности, так что я имею выбрал исследование, чтобы найти надежный и отзывчивый способ проверки наличия соединения с сервером базы данных 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 НЕ был успешным!

Смежные вопросы