c#

时间:2017-12-28 20:52:37

标签: c# google-cloud-platform google-cloud-firestore real-time-updates

我正在尝试使用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调用,因此会有一些费用。也许这就是它以这种方式运作的原因?

由于

1 个答案:

答案 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));
};