Xamarin后台断开信号器

Xamarin background disconnected signalr

我正在使用 Signalr 服务实现聊天的 Xamarin Forms 中创建一个应用程序。聊天在 UWP 版本和 Android 模拟器中完美运行,当我在我的 phone (Android) 上调试时也是如此,但是当我断开 phone从 PC 开始混乱。问题是我认为当应用程序进入后台时,它会与 Signalr 服务器断开连接。

我试过自动重连,甚至更改ServerTimeout和KeepAliveInterval的时间。但我没有成功。应该注意的是,我住的地方还有主要的连接问题,但我的理论仍然是应用程序进入后台。

这是我初始化服务的代码(我使用的是单例服务)。

       hubConnection = new HubConnectionBuilder()
        .WithUrl(URL, options =>
        {
            options.AccessTokenProvider = () => Task.FromResult(_myAccessToken);
        })
        .WithAutomaticReconnect()
        //.WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
        //.WithAutomaticReconnect(new RandomRetryPolicy())
        .Build();

这是我在连接关闭时连接的代码

            hubConnection.Closed += async (error) =>
            {
                OnConnectionClosed?.Invoke(this, new MessageEventArgs("Connection closed...", 
                string.Empty));
                IsConnected = false;

                await Task.Delay(new Random().Next(0, 5) * 1000);
                try { await ReConnectAsync(); } catch (Exception ex) { Debug.WriteLine(ex); }
            };

这是我的连接代码

        public async Task ReConnectAsync()
        {
            await ConnectAsync();
        }

        public async Task ConnectAsync()
        {
            if (IsConnected)
            {
                return;
            }

            Debug.WriteLine(hubConnection.State);

            if (hubConnection.State== HubConnectionState.Disconnected)
            {
                await hubConnection.StartAsync();

                //CancellationToken cancellationToken = new CancellationToken();
                //await ConnectWithRetryAsync(hubConnection, cancellationToken);
            }

            IsConnected = true;
        }

我还能尝试什么来防止它在 Android 上断开连接或者我的代码会做错什么?

除非您有前台服务 运行,否则您将无法在 Android 上保持 SignalR 连接,这实际上使应用程序保持活动状态。这就是音乐应用程序等可以在后台继续运行的方式。

前台服务还需要向用户显示它是 运行 的通知。

Xamarin 提供了一个很好的小示例,展示了如何在此处创建前台服务 https://github.com/xamarin/monodroid-samples/tree/master/ApplicationFundamentals/ServiceSamples/ForegroundServiceDemo

本质上你创建了一个服务:

[Service]
public class MyForegroundService : Service
{
}

然后你从你的 Activity 开始它的意图是:

var intent = new Intent(this, typeof(MyForegroundService));
StartForegroundService(intent);

在您的服务中,您需要在 OnStartCommand 覆盖中调用 StartForeground,否则服务将被终止。

问题是。您真的需要前台服务并在后台保留 运行 SignalR 吗?

您是否考虑过偶尔轮询后端以获取最新消息?

您是否考虑过在用户收到新消息时发送推送通知?

如果您决定也以 iOS 为目标,您将遇到更大的限制。在那里你将不可能保持你的 SignalR 连接。