我正在尝试使用Google.Cloud.Firestore.V1Beta1
在c#中使用Cloud Firestore订阅实时更新。我正在使用以下代码,它会在短时间内接收更新,直到关闭流。有人有FirestoreClient.Listen
工作吗?
// Create client
FirestoreClient firestoreClient = FirestoreClient.Create();
// Initialize streaming call, retrieving the stream object
FirestoreClient.ListenStream duplexStream = firestoreClient.Listen();
// Create task to do something with responses from server
Task responseHandlerTask = Task.Run(async () =>
{
IAsyncEnumerator<ListenResponse> responseStream = duplexStream.ResponseStream;
while (await responseStream.MoveNext())
{
ListenResponse response = responseStream.Current;
Console.WriteLine(response);
}
});
// Send requests to the server
var citiesPath = string.Format("projects/{0}/databases/{1}/documents/cities/CJThcwCipOtIEAm2tEMY", projectId, databaseId);
// Initialize a request
var dt = new DocumentsTarget { };
dt.Documents.Add(citiesPath);
ListenRequest request = new ListenRequest
{
Database = new DatabaseRootName(projectId, databaseId).ToString(),
AddTarget = new Target
{
Documents = dt
}
};
// Stream a request to the server
await duplexStream.WriteAsync(request);
// Await the response handler.
// This will complete once all server responses have been processed.
Console.WriteLine("Awaiting responseHandlerTask");
await responseHandlerTask;
编辑1: 我已经尝试将expiration明确设置为永不过期,但仍然没有运气,我得到5分钟然后收到RST_STREAM。
//Setup no expiration for the listen
CallSettings listenSettings = CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.None));
// Initialize streaming call, retrieving the stream object
FirestoreClient.ListenStream duplexStream = firestoreClient.Listen(listenSettings);
编辑2: 它似乎有点像kludge,但我发现它可以跟踪最后一次resetToken,捕获异常,然后用请求令牌重启请求。我已经更新了使原始请求采用可选resumeToken的代码。
ListenRequest request = new ListenRequest
{
Database = new DatabaseRootName(projectId, databaseId).ToString(),
AddTarget = new Target
{
Documents = dt
}
};
if (resumeToken != null)
{
Console.WriteLine(string.Format("Resuming a listen with token {0}", resumeToken.ToBase64()));
request.AddTarget.ResumeToken = resumeToken;
}
// Stream a request to the server
await duplexStream.WriteAsync(request);
这并不完美,但我认为这是Google在Node.js中实现它的方式。它确实导致每5分钟进行一次API调用,因此会有一些费用。也许这就是它以这种方式运作的原因?
由于
答案 0 :(得分:1)
在Jon完成官方支持之前,如果您需要,可以使用我放在一起的东西。 https://github.com/cleversolutions/FirebaseDotNetRamblings/blob/master/FirebaseDocumentListener.cs它是一种扩展方法,您可以将其放入项目中并使用如下:
//Create our database connection
FirestoreDb db = FirestoreDb.Create(projectId);
//Create a query
CollectionReference collection = db.Collection("cities");
Query qref = collection.Where("Capital", QueryOperator.Equal, true);
//Listen to realtime updates
FirebaseDocumentListener listener = qref.AddSnapshotListener();
//Listen to document changes
listener.DocumentChanged += (obj, e) =>
{
var city = e.DocumentSnapshot.Deserialize<City>();
Console.WriteLine(string.Format("City {0} Changed/Added with pop {1}", city.Name, city.Population));
};