[英]MongoDB 3.6.x change stream marshalling/unmarshalling in NodeJS driver
我正在使用MongoDB 3.6.2的更改流(使用Mongo NodeJS驅動程序3.0.1)嘗試將可恢復的數據流實現到瀏覽器。 所以在我的代碼中的某些時候,我在恢復令牌上做了一個JSON.stringify,我在更新期間回來了(即更改流中更新的_id)。 我通過電匯將其發送到前端應用程序,然后當斷開連接並隨后重新連接時,此信息將被發送回服務器以讓它知道從何處繼續。 但是,我似乎不能簡單地將此JSON對象提供給驅動程序以從中恢復,因為我將恢復令牌的無效類型視為運行時錯誤。
stringify導致的一個例子:
{ “_data”: “glpeTK8AAAABRmRfaWQAZFoygBEXtikxY6F / zgBaEAQkFlJHID5PgaLDUFQD2jMyBA ==”}
實際的恢復標記似乎是以下形式的專用緩沖區對象:
{
_data: {
buffer: Buffer(49),
position = 49,
sub_type = 0,
_bsontype = "Binary"
}
}
當然,我的問題是將字符串恢復為實際的恢復令牌。 Buffer(49)本身似乎被轉換為base64字符串,然后將其分配給_data。 我不確定其他領域是什么。 我無法找到關於這種令牌的編組/解組的大量文檔來處理流式數據到客戶端的恢復(給定多個節點服務器進行擴展,只需將令牌保留在服務器上並不是一個好的選擇,因為該服務器可能會關閉並且客戶端嘗試重新連接,因此它具有與其停止的位置相關的令牌,並且它連接的下一個服務器從那里獲取是最佳的。
一般來說,恢復令牌似乎已被開發人員嚴格鎖定,它包含我可以使用的有價值的信息(我們正在使用什么集合,更新的時間戳等),但這些都不可用(盡管這顯然是他們將為3.7)添加的功能。 同樣地,我甚至無法為當前時刻獲取給定集合的恢復令牌(如果我已經閱讀了一個集合並且沒有任何更新,但又不想完全閱讀它,那么非常有用)如果我斷開/重新連接只是因為集合沒有發生更新)。 但希望其中一些設施將被添加,因為Mongo意識到它們的用處。
如果沒有涉及編組/解組(即令牌作為服務器上的對象並且未轉換為線路可接受的形式),我已使用恢復令牌成功測試以恢復流。 但這在規模化的環境中並不是很有用。
為了防止其他人遇到這個問題,我想我會發布我目前的解決方案,不過我仍然會邀請更好的解決方案。
通過BSON的魔力,我只需序列化恢復令牌,將該緩沖區轉換為base64,然后將其發送到瀏覽器。 然后當瀏覽器在斷開/重新連接后將其發回時,我只需從base64創建一個緩沖區,並使用bson反序列化該緩沖區。 生成的令牌就像一個魅力。
即,我對更新令牌的編組看起來像這樣的代碼:
b64String = bson.serialize(resumeToken).toString('base64');
並且,我在斷開/重新連接后發送的base64令牌的解組看起來像這樣的代碼:
token = bson.deserialize(Buffer.from(b64String, 'base64'));
或者,您可以使用MongoDB Extended JSON庫: npm模塊mongodb-extjson來字符串化和解析令牌。
例如:
const EJSON = require("mongodb-extjson");
resumeToken = EJSON.stringify(changeStreamDoc._id);
並恢復:
changeStream = collection.watch([], { resumeAfter: EJSON.parse(resumeToken) });
在mongodb-extjson
版本2.1.0和MongoDB v3.6.3上測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.