簡體   English   中英

MongoDB 3.6.x在NodeJS驅動程序中更改流編組/解組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM