MongoDB 3.6.x在NodeJS驱动程序中更改流编组/解组

问题描述 投票:3回答:2

我正在使用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意识到它们的用处。

如果没有涉及编组/解组(即令牌作为服务器上的对象并且未转换为线路可接受的形式),我已使用恢复令牌成功测试以恢复流。但这在规模化的环境中并不是很有用。

javascript node.js mongodb
2个回答
1
投票

为了防止其他人遇到这个问题,我想我会发布我目前的解决方案,不过我仍然会邀请更好的解决方案。

通过BSON的魔力,我只需序列化恢复令牌,将该缓冲区转换为base64,然后将其发送到浏览器。然后当浏览器在断开/重新连接后将其发回时,我只需从base64创建一个缓冲区,并使用bson反序列化该缓冲区。生成的令牌就像一个魅力。

即,我对更新令牌的编组看起来像这样的代码:

b64String = bson.serialize(resumeToken).toString('base64');

并且,我在断开/重新连接后发送的base64令牌的解组看起来像这样的代码:

token = bson.deserialize(Buffer.from(b64String, 'base64'));

0
投票

或者,您可以使用MongoDB Extended JSON库:npm module 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上测试过

© www.soinside.com 2019 - 2024. All rights reserved.