Firebase Xamarin.Forms - 并发连接过多
Firebase Xamarin.Forms - too many concurrent connections
目前我正在与一个使用 Xamarin.Forms 的小团队开发应用程序。我们需要与数据库通信以获取一些位置、订单详细信息等。为此,我们正在使用 Google 的 Firebase(实时数据库)。当我们写入和读取数据时一切正常。但是在 Firebase 控制台的使用选项卡中,有 超过 50 个并发连接。这很奇怪,因为我们目前正在开发并且没有发布我们应用程序的任何版本。最多应该有 5 个并发连接(我们是一个 5 人的团队)。
我们正在使用 NuGet-Package FirebaseDatabase.net (4.0.4) https://www.nuget.org/packages/FirebaseDatabase.net/ 来读取和写入数据库。
多个监听器用于对数据库中的变化做出反应(到目前为止,似乎每个监听器都占用一个连接,这似乎不正确)。
下面的代码显示了在构造函数中调用一次的 FirebaseClient 的初始化。
private FirebaseClient InitDbClient()
{
var dbClient = new FirebaseClient(Constants.Values.FIREBASE_DATABASE_URL, new FirebaseOptions()
{
AuthTokenAsyncFactory = () => Task.FromResult(_authToken)
});
return dbClient;
}
每个侦听器的实现方式与以下代码类似:
public IDisposable SubscribeToChatMessages(string orderID)
{
var observer = _dbClient.Child($"orders/{orderID}/Chat/Messages").AsObservable<JObject>();
var subscribe = observer.Subscribe(t =>
{
if (t.EventType == Firebase.Database.Streaming.FirebaseEventType.Delete)
{
return;
}
ChatMessage msg;
try
{
msg = JsonConvert.DeserializeObject<ChatMessage>(t.Object.ToString());
}catch(Exception e)
{
Debug.WriteLine(e.Message);
msg = new ChatMessage() { C = null, T = new DateTime(), U = null };
}
//...do something with the chat message
});
return subscribe;
}
由于我不确定问题出在哪里,所以我只是将我们的一些代码放在这里。如果有人对此问题有解决方案或知道我们可以尝试什么,那就太好了。
我自己找到了答案。正如我已经怀疑的那样,每个侦听器都使用一个连接。原因很简单:这个包是建立在 firebase 的其余 api 之上的。在其他一些问题中提到每个侦听器基本上都是一个流式网络套接字(或类似的东西)。其中每一个都消耗一个并发连接。
作为解决方法(减少并发连接数),我将所有实际上不需要的侦听器替换为计时器和简单数据库请求的组合。为了能够查询新数据,我向数据本身添加了时间戳。这允许我使用类似于
的数据库查询
dbClient.Child($"orders/{orderID}/Chat/Messages").orderBy("Time").startAt(lastRead).OnceAsync<>()...
目前我正在与一个使用 Xamarin.Forms 的小团队开发应用程序。我们需要与数据库通信以获取一些位置、订单详细信息等。为此,我们正在使用 Google 的 Firebase(实时数据库)。当我们写入和读取数据时一切正常。但是在 Firebase 控制台的使用选项卡中,有 超过 50 个并发连接。这很奇怪,因为我们目前正在开发并且没有发布我们应用程序的任何版本。最多应该有 5 个并发连接(我们是一个 5 人的团队)。
我们正在使用 NuGet-Package FirebaseDatabase.net (4.0.4) https://www.nuget.org/packages/FirebaseDatabase.net/ 来读取和写入数据库。
多个监听器用于对数据库中的变化做出反应(到目前为止,似乎每个监听器都占用一个连接,这似乎不正确)。
下面的代码显示了在构造函数中调用一次的 FirebaseClient 的初始化。
private FirebaseClient InitDbClient()
{
var dbClient = new FirebaseClient(Constants.Values.FIREBASE_DATABASE_URL, new FirebaseOptions()
{
AuthTokenAsyncFactory = () => Task.FromResult(_authToken)
});
return dbClient;
}
每个侦听器的实现方式与以下代码类似:
public IDisposable SubscribeToChatMessages(string orderID)
{
var observer = _dbClient.Child($"orders/{orderID}/Chat/Messages").AsObservable<JObject>();
var subscribe = observer.Subscribe(t =>
{
if (t.EventType == Firebase.Database.Streaming.FirebaseEventType.Delete)
{
return;
}
ChatMessage msg;
try
{
msg = JsonConvert.DeserializeObject<ChatMessage>(t.Object.ToString());
}catch(Exception e)
{
Debug.WriteLine(e.Message);
msg = new ChatMessage() { C = null, T = new DateTime(), U = null };
}
//...do something with the chat message
});
return subscribe;
}
由于我不确定问题出在哪里,所以我只是将我们的一些代码放在这里。如果有人对此问题有解决方案或知道我们可以尝试什么,那就太好了。
我自己找到了答案。正如我已经怀疑的那样,每个侦听器都使用一个连接。原因很简单:这个包是建立在 firebase 的其余 api 之上的。在其他一些问题中提到每个侦听器基本上都是一个流式网络套接字(或类似的东西)。其中每一个都消耗一个并发连接。
作为解决方法(减少并发连接数),我将所有实际上不需要的侦听器替换为计时器和简单数据库请求的组合。为了能够查询新数据,我向数据本身添加了时间戳。这允许我使用类似于
的数据库查询dbClient.Child($"orders/{orderID}/Chat/Messages").orderBy("Time").startAt(lastRead).OnceAsync<>()...