目前,我正在与一个小团队一起使用Xamarin.Forms开发一款应用程序。我们需要与数据库进行通信,以获取一些位置、订单详细信息等。为此,我们正在使用谷歌的Firebase(实时数据库(。当我们写和读数据时,一切都很好。但是,在Firebase控制台的使用选项卡中,存在超过50个并发连接。这很奇怪,因为我们目前正在开发,没有发布任何版本的应用程序。最多应该有5个并发连接(我们是一个5人的团队(。
我们正在使用NuGet软件包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的rest api之上构建的。在另一个问题中,有人提到,每个侦听器基本上都是一个流式网络套接字(或类似的东西(。其中每一个都使用一个并发连接。
作为一种变通方法(减少并发连接的数量(,我用定时器和简单的数据库请求的组合替换了所有实际上不需要的侦听器。为了能够查询新数据,我在数据本身添加了时间戳。这允许我使用类似的数据库查询
dbClient.Child($"orders/{orderID}/Chat/Messages").orderBy("Time").startAt(lastRead).OnceAsync<>()...