如何在 C# MongoDB 驱动程序 v2.0 中获取连接状态?
How to get connection status in the C# MongoDB driver v2.0?
我们开始使用新的 MongoDB driver v2,我们无法了解我们是否已连接到数据库。
我们的存储库代码:
var client = new MongoClient("mongodb://{wrong-host}:{wrong-port}/{dbbname}");
var database = client.GetDatabase(url.DatabaseName);
其中 wrong-host
和 wrong-port
是无效值。
首先我们认为如果没有人在指定地址上侦听但驱动程序没有抛出异常,则会引发异常。
下一步是在数据库上调用方法:
var dbs = client.ListDatabasesAsync().Result.ToListAsync().Result;
这里我们冻结了 30 秒,然后是异常。我们不适合等待 30 秒来了解我们是否已连接。
System.TimeoutException: A timeout occured after 30000ms selecting a
server using CompositeServerSelector{ Selectors =
ReadPreferenceServerSelector{ ReadPreference = { Mode = Primary,
TagSets = [] } }, LatencyLimitingServerSelector{ AllowedLatencyRange =
00:00:00.0150000 } }. Client view of cluster state is { ClusterId :
"1", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId:
"{ ClusterId : 1, EndPoint : "****" }", EndPoint: "****", State:
"Disconnected", Type: "Unknown", HeartbeatException:
"MongoDB.Driver.MongoConnectionException: An exception occurred while
opening a connection to the server. --->
System.Net.Sockets.SocketException: No connection could be made
because the target machine actively refused it ******
最后我们尝试设置不同的超时,但没有任何改变。
var client = new MongoClient(new MongoClientSettings
{
SocketTimeout = TimeSpan.FromSeconds(1),
MaxConnectionIdleTime = TimeSpan.FromSeconds(1),
MaxConnectionLifeTime = TimeSpan.FromSeconds(1),
ConnectTimeout = TimeSpan.FromSeconds(1),
Servers = url.Servers
});
所以问题是我们如何在短时间间隔〜(1-2)秒内知道我们是否连接到mongo?
[UPD]
我们目前的解决方案是:
private IMongoDatabase Connect(string connectionString, TimeSpan timeout)
{
var url = MongoUrl.Create(connectionString);
var client = new MongoClient(url);
var db = client.GetDatabase(url.DatabaseName);
var pingTask = db.RunCommandAsync<BsonDocument>(new BsonDocument("ping", 1));
pingTask.Wait(timeout);
if (pingTask.IsCompleted)
log.InfoFormat("Connected to: {0}.", connectionString);
else
throw new TimeoutException(string.Format("Failed to connect to: {0}.", connectionString));
return db;
}
用法
database = Connect(connectionString, TimeSpan.FromSeconds(1));
这个 issue 有下一个解决方法:
var client = new MongoClient(new MongoClientSettings
{
Server = new MongoServerAddress("xxxx"),
ClusterConfigurator = builder =>
{
builder.ConfigureCluster(settings => settings.With(serverSelectionTimeout: TimeSpan.FromSeconds(10)));
}
});
随着新 API :
try
{
MongoClient client = new MongoClient("xxx");
// if you're running localhost let the parameter empty
var db = client.GetDatabase("dbName");
var collection = db.GetCollection<BsonDocument>("collectionName");
var filter1 = Builders<BsonDocument>.Filter.Empty;
var filter = new BsonDocument();
var count = 0;
using (var cursor = await collection.FindAsync(filter))
{
while (await cursor.MoveNextAsync())
{
var batch = cursor.Current;
foreach (var document in batch)
{
count++;
}
}
}
MessageBox.Show(count.ToString());
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
我们开始使用新的 MongoDB driver v2,我们无法了解我们是否已连接到数据库。
我们的存储库代码:
var client = new MongoClient("mongodb://{wrong-host}:{wrong-port}/{dbbname}");
var database = client.GetDatabase(url.DatabaseName);
其中 wrong-host
和 wrong-port
是无效值。
首先我们认为如果没有人在指定地址上侦听但驱动程序没有抛出异常,则会引发异常。
下一步是在数据库上调用方法:
var dbs = client.ListDatabasesAsync().Result.ToListAsync().Result;
这里我们冻结了 30 秒,然后是异常。我们不适合等待 30 秒来了解我们是否已连接。
System.TimeoutException: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode = Primary, TagSets = [] } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "****" }", EndPoint: "****", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it ******
最后我们尝试设置不同的超时,但没有任何改变。
var client = new MongoClient(new MongoClientSettings
{
SocketTimeout = TimeSpan.FromSeconds(1),
MaxConnectionIdleTime = TimeSpan.FromSeconds(1),
MaxConnectionLifeTime = TimeSpan.FromSeconds(1),
ConnectTimeout = TimeSpan.FromSeconds(1),
Servers = url.Servers
});
所以问题是我们如何在短时间间隔〜(1-2)秒内知道我们是否连接到mongo?
[UPD]
我们目前的解决方案是:
private IMongoDatabase Connect(string connectionString, TimeSpan timeout)
{
var url = MongoUrl.Create(connectionString);
var client = new MongoClient(url);
var db = client.GetDatabase(url.DatabaseName);
var pingTask = db.RunCommandAsync<BsonDocument>(new BsonDocument("ping", 1));
pingTask.Wait(timeout);
if (pingTask.IsCompleted)
log.InfoFormat("Connected to: {0}.", connectionString);
else
throw new TimeoutException(string.Format("Failed to connect to: {0}.", connectionString));
return db;
}
用法
database = Connect(connectionString, TimeSpan.FromSeconds(1));
这个 issue 有下一个解决方法:
var client = new MongoClient(new MongoClientSettings
{
Server = new MongoServerAddress("xxxx"),
ClusterConfigurator = builder =>
{
builder.ConfigureCluster(settings => settings.With(serverSelectionTimeout: TimeSpan.FromSeconds(10)));
}
});
随着新 API :
try
{
MongoClient client = new MongoClient("xxx");
// if you're running localhost let the parameter empty
var db = client.GetDatabase("dbName");
var collection = db.GetCollection<BsonDocument>("collectionName");
var filter1 = Builders<BsonDocument>.Filter.Empty;
var filter = new BsonDocument();
var count = 0;
using (var cursor = await collection.FindAsync(filter))
{
while (await cursor.MoveNextAsync())
{
var batch = cursor.Current;
foreach (var document in batch)
{
count++;
}
}
}
MessageBox.Show(count.ToString());
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}