Reputation: 10872
I use MongoDB
drivers to connect to the database. When my form loads, I want to set up connection and to check whether it is ok or not. I do it like this:
var connectionString = "mongodb://localhost";
var client = new MongoClient(connectionString);
var server = client.GetServer();
var database = server.GetDatabase("reestr");
But I do not know how to check connection. I tried to overlap this code with try-catch
, but to no avail. Even if I make an incorrect connectionString, I still can not get any error message.
Upvotes: 41
Views: 80935
Reputation: 39
If you are just checking for testing and terminal output will do the trick then try this where usersCollection is the full client string to the database and the collection:
console.log(usersCollection); usersCollection.insertOne(this.data);
You should see something like this in the terminal:
Collection {
s: {
db: Db { s: [Object], client: [MongoClient] },
options: {
raw: false,
useBigInt64: false,
promoteLongs: true,
promoteValues: true,
promoteBuffers: false,
ignoreUndefined: false,
bsonRegExp: false,
serializeFunctions: false,
fieldsAsRaw: {},
enableUtf8Validation: true,
readPreference: [ReadPreference]
},
namespace: MongoDBCollectionNamespace {
db: 'ComplexApp',
collection: 'users'
},
pkFactory: { createPk: [Function: createPk] },
readPreference: ReadPreference {
mode: 'primary',
tags: undefined,
hedge: undefined,
maxStalenessSeconds: undefined,
minWireVersion: undefined
},
bsonOptions: {
raw: false,
useBigInt64: false,
promoteLongs: true,
promoteValues: true,
promoteBuffers: false,
ignoreUndefined: false,
bsonRegExp: false,
serializeFunctions: false,
fieldsAsRaw: {},
enableUtf8Validation: true
},
readConcern: undefined,
writeConcern: undefined
},
client: <ref *1> MongoClient {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
mongoLogger: MongoLogger {
error: [Function: bound log],
warn: [Function: bound log],
info: [Function: bound log],
debug: [Function: bound log],
trace: [Function: bound log],
componentSeverities: [Object],
maxDocumentLength: 1000,
logDestination: [Object]
},
s: {
url: 'mongodb://0.0.0.0:27017/',
bsonOptions: [Object],
namespace: [MongoDBNamespace],
hasBeenClosed: false,
sessionPool: [ServerSessionPool],
activeSessions: Set(0) {},
options: [Getter],
readConcern: [Getter],
writeConcern: [Getter],
readPreference: [Getter],
isMongoClient: [Getter]
},
topology: Topology {
_events: [Object: null prototype],
_eventsCount: 26,
_maxListeners: undefined,
client: [Circular *1],
selectServerAsync: [Function (anonymous)],
s: [Object],
[Symbol(kCapture)]: false,
[Symbol(waitQueue)]: [List]
},
connectionLock: undefined,
[Symbol(kCapture)]: false,
[Symbol(options)]: [Object: null prototype] {
hosts: [Array],
compressors: [Array],
connectTimeoutMS: 30000,
directConnection: false,
driverInfo: {},
enableUtf8Validation: true,
forceServerObjectId: false,
heartbeatFrequencyMS: 10000,
loadBalanced: false,
localThresholdMS: 15,
maxConnecting: 2,
maxIdleTimeMS: 0,
maxPoolSize: 100,
minPoolSize: 0,
minHeartbeatFrequencyMS: 500,
monitorCommands: false,
noDelay: true,
pkFactory: [Object],
raw: false,
readPreference: [ReadPreference],
retryReads: true,
retryWrites: true,
serverMonitoringMode: 'auto',
serverSelectionTimeoutMS: 30000,
socketTimeoutMS: 0,
srvMaxHosts: 0,
srvServiceName: 'mongodb',
waitQueueTimeoutMS: 0,
zlibCompressionLevel: 0,
dbName: 'test',
userSpecifiedAuthSource: false,
userSpecifiedReplicaSet: false,
mongoLoggerOptions: [Object],
metadata: [Object],
[Symbol(@@mdb.enableMongoLogger)]: false
}
}
}
Upvotes: 0
Reputation: 23
This is a solution by using the try-catch approach,
var database = client.GetDatabase("YourDbHere");
bool isMongoConnected;
try
{
await database.RunCommandAsync((Command<BsonDocument>)"{ping:1}");
isMongoConnected = true;
}
catch(Exception)
{
isMongoConnected = false;
}
so when it fails to connect to the database, it will throw an exception and we can handle our bool flag there.
Upvotes: 1
Reputation: 188
Here a simple extension method to ping mongodb server
public static class MongoDbExt
{
public static bool Ping(this IMongoDatabase db, int secondToWait = 1)
{
if (secondToWait <= 0)
throw new ArgumentOutOfRangeException("secondToWait", secondToWait, "Must be at least 1 second");
return db.RunCommandAsync((Command<MongoDB.Bson.BsonDocument>)"{ping:1}").Wait(secondToWait * 1000);
}
}
You can use it like so:
var client = new MongoClient("yourConnectionString");
var database = client.GetDatabase("yourDatabase");
if (!database.Ping())
throw new Exception("Could not connect to MongoDb");
Upvotes: 3
Reputation: 329
I've had the same question as the OP, and tried every and each solution I was able to find on Internet... Well, none of them worked to my true satisfaction, so I've opted for a research to find a reliable and responsive way of checking if connection to a MongoDB Database Server is alive. And this without to block the application's synchronous execution for too long time period...
So here are my prerequisites:
I've provided a fresh MongoDB Installation (version 3.6) on the default localhost URL: mongodb://localhost:27017. I've also written down another URL, where there was no MongoDB Database Server: mongodb://localhost:27071.
I'm also using the C# Driver 2.4.4 and do not use the legacy implementation (MongoDB.Driver.Legacy assembly).
So my expectations are, when I'm checking the connection to the first URL, it should give to me the Ok for a alive connection to an existing MongoDB server, when I'm checking the connection to the second URL it should give to me the Fail for a non-existing MongoDB server...
Using the IMongoDatabase.RunCommand method, queries the server and causes the server response timeout to elapse, thus not qualifying against the prerequisites. Furthermore after the timeout, it breaks with a TimeoutException, which requires additional exception handling.
This actual SO question and also this SO question have delivered the most of the start information I needed for my solution... So guys, many thanks for this!
Now my solution:
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;
}
The idea behind this is the MongoDB Server does not react (and seems to be non-existing) until a real attempt is made to access some resource on the server (for example a database). But retrieving some resource alone is not enough, as the server still has no updates to its state in the server's Cluster Description. This update comes first, when the resource is retrieved again. From this time point, the server has valid Cluster Description and valid data inside it...
Generally it seems to me, the MongoDB Server does not proactivelly propagate its Cluster Description to all connected clients. Rather then, each client receives the description, when a request to the server has been made. If some of you fellows have more information on this, please either confirm or deny my understandings on the topic...
Now when we target an invalid MongoDB Server URL, then the Cluster Description remains invalid and we can catch and deliver an usable signal for this case...
So the following statements (for the valid 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!"));
will print out
Connection to mongodb://localhost:27017 was successful!
and the statements (for the invalid 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!"));
will print out
Connection to mongodb://localhost:27071 was NOT successful!
Upvotes: 3
Reputation: 2858
full example for 2.4.3 - where "client.GetServer()" isn't available. based on "Paul Keister" answer.
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
}
Upvotes: 29
Reputation: 514
If you want to handle connection issues in your program you can use the ICluster.Description
event.
When the MongoClient
is created, it will continue to attempt connections in the background until it succeeds.
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;
}
}
Upvotes: -1
Reputation: 13097
To ping the server with the new 3.0 driver its:
var database = client.GetDatabase("YourDbHere");
database.RunCommandAsync((Command<BsonDocument>)"{ping:1}")
.Wait();
Upvotes: 49
Reputation: 46331
There's a ping method for that:
var connectionString = "mongodb://localhost";
var client = new MongoClient(connectionString);
var server = client.GetServer();
server.Ping();
Upvotes: 28