0

我正在开发一个 Xamarin Forms 应用程序,该应用程序连接到 Azure SignalR 服务以获取服务器端事件,以通知应用程序有关服务器上发生的某些事件。

我创建了一个能够与 SignalR 服务建立此连接的后台服务,但是一段时间后看起来设备进入Doze Mode导致服务失去与 SignalR 服务器的 tcp 连接。发生这种情况时,我看到以下错误:

Server timeout (30000.00ms) elapsed without receiving a message from the server.

我有一个重试逻辑来重新连接,即使失败,因为在这种状态下看起来没有互联网连接。但是,如果在此重试周期中,如果我让设备唤醒,则连接成功。

所以我的问题是,无论设备状态如何,我如何确保我的服务始终可以访问互联网以防止此类问题。

更新 1

这是我正在做的事情所要求的代码:

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;
        }
    }
}
4

1 回答 1

0

由于超时,SignalR 在这种情况下会自动关闭连接。我强烈建议将通知想法更改为推送通知。Azure 提供了这样的服务。

于 2019-08-29T08:41:25.270 回答