I am developing a Xamarin Forms app that connects to a Azure SignalR service to get server side events to notify the application about some events happening on the server.
I have created a background service that is able make this connection to SignalR service, however after a while looks like the device enters Doze Mode
which is causing the service to loose its tcp connection to the SignalR server.
I see the following error when this happens:
Server timeout (30000.00ms) elapsed without receiving a message from the server.
I have a retry logic built to reconnect even that fails as there is no internet connection looks like in this state. however if during this retry cycle, if I get the device to wakeup, the connection succeeds.
So my question is, how can I ensure that my service always has internet access to prevent such issue irrespective of the device state.
Update 1
here is the code requested for what I am doing:
public string AssetId { get; private set; }
public async Task ConnectAsync(string assetId)
{
try
{
AssetId = assetId;
if (connection == null)
{
var client = new HttpClient(); //new HttpClient(new Xamarin.Android.Net.AndroidClientHandler());
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("asset-id", assetId);
string negotiateJson = await client.GetStringAsync(Constants.SignalRNegotiateFunctionURL);
NegotiateInfo negotiate = JsonConvert.DeserializeObject<NegotiateInfo>(negotiateJson);
connection = new HubConnectionBuilder()
.WithUrl(negotiate.Url, options =>
{
options.AccessTokenProvider = async () => negotiate.AccessToken;
})
.Build();
connection.Closed += Connection_Closed;
connection.On<JObject>("OnAssetApproaching", OnAssetApproachingSignalREvent);
}
IsConnected = true;
await connection.StartAsync();
}
catch (Exception ex)
{
IsConnected = false;
}
}
async Task Connection_Closed(Exception arg)
{
if (IsConnected)
{
var retryCount = 0;
while (retryCount < 5)
{
try
{
await connection?.StopAsync();
await Task.Delay(new Random().Next(0, 5) * 1000);
await connection.StartAsync();
if (connection.State == HubConnectionState.Connected)
{
break;
}
}
catch (Exception ex)
{
retryCount++;
}
}
if (connection.State == HubConnectionState.Disconnected)
{
IsConnected = false;
}
}
}