我使用MongoDB 3.6.2的更改流(使用Mongo NodeJS驱动程序3.0.1)尝试将可恢复的数据流实现到浏览器。所以在我的代码中的某些时候,我在恢复令牌上做了一个JSON.stringify,我在更新期间回来了(即更改流中更新的_id)。我通过电汇将其发送到前端应用程序,然后当断开连接并随后重新连接时,此信息将被发送回服务器以让它知道从何处继续。但是,我似乎不能简单地将此JSON对象提供给驱动程序以便从恢复标记的无效类型作为运行时错误恢复。
stringify导致的一个例子:
{ “_数据”: “glpeTK8AAAABRmRfaWQAZFoygBEXtikxY6F / zgBaEAQkFlJHID5PgaLDUFQD2jMyBA ==”}
实际的恢复标记似乎是以下形式的专用缓冲区对象:
{
_data: {
buffer: Buffer(49),
position = 49,
sub_type = 0,
_bsontype = "Binary"
}
}
我的问题当然是将字符串恢复为实际的恢复令牌。 Buffer(49)本身似乎被转换为base64字符串,然后将其分配给_data。我不确定其他领域是什么。我无法找到关于这种令牌的编组/解组的大量文档来处理流式数据到客户端的恢复(给定多个节点服务器进行扩展,只需将令牌保留在服务器上并不是一个好的选择,因为该服务器可能会关闭并且客户端尝试重新连接,因此它具有与其停止的位置相关的令牌以及它连接到的最后一个服务器是最佳的。
一般来说,恢复令牌似乎已被开发人员严格锁定,它包含我可以使用的有价值信息(我们所使用的集合,更新的时间戳等),但这些都不可用于我(虽然它显然是一个功能,他们将添加3.7)。同样地,我甚至无法为当前时刻获取给定集合的恢复令牌(如果我已经阅读了一个集合并且没有任何更新,但又不想完全阅读它,那么非常有用)如果我断开/重新连接只是因为集合没有发生更新)。但是,希望其中一些设施将被添加,因为Mongo意识到它们的用处。
如果没有涉及编组/解组(即令牌作为服务器上的对象并且未转换为可接受的电线形式),我已成功使用恢复令牌进行测试以恢复流。但这在规模化的环境中并不是很有用。
答案 0 :(得分:1)
万一其他人有这个问题,我想我会发布我目前的解决方案,不过我仍然会邀请更好的解决方案。
通过BSON的魔力,我只需序列化恢复令牌,将该缓冲区转换为base64,然后将其发送到浏览器。然后当浏览器在断开/重新连接后将其发回时,我只需从base64创建一个缓冲区,并使用bson反序列化该缓冲区。生成的令牌就像魅力一样。
即,我对更新令牌的编组看起来像这样的代码:
b64String = bson.serialize(resumeToken).toString('base64');
而且,我在断开/重新连接后发送的base64令牌的解组看起来像这段代码:
token = bson.deserialize(Buffer.from(b64String, 'base64'));
答案 1 :(得分: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