Latency timeout using CosmosDB from Android Xamarin

283 Views Asked by At

I am developing an app using Xamarin using Visual Studio for Mac. I am writing C# to target both iOS and Android.

We are also using CosmosDB on Microsoft Azure.

The problem comes about when trying to get Android to access CosmosDB. Please note that I am using the Mongo API for Cosmos.

The error message I get in Android is as follows:

A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode : Primary } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "2", ConnectionMode : "ReplicaSet", Type : "ReplicaSet", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 2, EndPoint : "Unspecified/aspire-cosmosdb.documents.azure.com:10255" }", EndPoint: "Unspecified/aspire-cosmosdb.documents.azure.com:10255", State: "Disconnected", Type: "Unknown" }] }.

This is my code:

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using MongoDB.Driver;

string dsn = "mongodb://myusername:[email protected]:10255/?ssl=true&replicaSet=globaldb";
string databaseName = "mydatabasename";

Debug.WriteLine("Initializing Cosmos DB!");
MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(dsn));
settings.SslSettings = new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 };
var mongoClient = new MongoClient(settings);
var db = mongoClient.GetDatabase(databaseName);

var databases = (await mongoClient.ListDatabasesAsync()).ToList();
foreach (var d in databases)
{
    Debug.WriteLine(d.AsBsonDocument);
}

This works 100% fine on xamarin.ios. Connects everytime. The code is pretty much copy and paste from the CosmosDB Quick start on the Azure Portal. I have also taken this code and put it in a C# Console app and it ALSO works. However, same code doesn't work on Android. Why?

I've tried this both on the Android simulator and a real Android device and both times get this 30 second timeout. I've also enabled the Internet permission on Android, but no joy. Please help!

I've referenced the latest packages via Nuget at the time of writing:

  • MongoDB.Driver -2.4.4
  • MongoDB.Driver.Core - 2.4.4
  • MongoDB.Bson - 2.4.4

Note: I have obfuscated the personal details from the dsn but it should show you the rough format of it. The actual dsn is a direct copy and paste of the cosmosdb dsn connection string from the Azure portal.

1

There are 1 best solutions below

1
Dirk R On BEST ANSWER

Okay so after a LOT of headbanging, the solution is fairly simple.

CosmosDB ONLY supports TLS 1.2.

Go into your Droid project settings (Right click on project > Options) and go to Android Build > SSL/TLS Implementation.

Mine was set to 'default'. I guess 'default' at the time of writing does not support TLS 1.2. At least not on Xamarin for the Mac anyway. This is quite a gotcha. Switch it over to Native TLS 1.2+ and magically it just works! Now able to connect to CosmosDB via Android.

enter image description here