首页 > 解决方案 > Xamarin 后台断开信号器

问题描述

我正在使用 Signalr 服务实现聊天的 Xamarin Forms 应用程序。聊天在 UWP 版本和 Android 模拟器中完美运行,所以当我在我的手机 (Android) 上进行调试时它确实如此,但是当我断开手机与 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 上断开连接,或者我的代码会做错什么?

标签: androidxamarinxamarin.formssignalrsignalr-hub

解决方案


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

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

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

本质上,您创建了一个服务:

[Service]
public class MyForegroundService : Service
{
}

然后你从你的 Activity 用一个 Intent 开始它:

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

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

问题是。你真的需要前台服务并在后台继续运行 SignalR 吗?

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

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

如果您也决定以 iOS 为目标,您将遇到更大的限制。在那里,您将无法保持 SignalR 连接处于活动状态。


推荐阅读