两台服务器之间的 DDP 不会重新连接

2023-12-10

我有两个流星应用程序通过不同服务器上的 DDP 连接,服务器 A 将数据发送到服务器 B。这就是它们的工作方式。

Server A

Items = new Meteor.Collection('items');
Items.insert({name: 'item 1'});
if (Meteor.isServer) {
  Meteor.publish('items', function() {
    return Items.find();
  });
}

Server B

var remote = DDP.connect('http://server-a/');
Items = new Meteor.Collection('items', remote); 

remote.subscribe('items');
Items.find().observe({
  added: function(item) {
    console.log(item);
  }
});

每次我打电话Items.insert(something)在服务器 A 上,在服务器 B 上,我在控制台上看到了我在服务器 A 上保存的对象的日志。但是,如果服务器 B 失去了 Internet 连接,则当服务器 B 重新连接到 Internet 时,服务器 A 上插入的数据将不再出现在服务器 B 上。

服务器B通过路由器连接到Internet。仅当我断开并重新连接路由器时才会出现此问题,而不是当我断开服务器与路由器的连接并重新连接时会出现此问题。两台服务器位于不同的网络上并通过 Internet 连接。

我在服务器 B 上创建了一个计时器来调用remote.status()但总是得到{ status: 'connected', connected: true, retryCount: 0 }连接或断开互联网时。

更新:重现步骤

我在github上创建了一个项目,其中包含测试代码https://github.com/camilosw/ddp-servers-test。服务器A安装在http://ddpserverstest-9592.onmodulus.net/

我的计算机通过无线电缆调制解调器连接到互联网。

  1. 在 server-b 文件夹上运行 mrt
  2. Go to http://ddpserverstest-9592.onmodulus.net/然后单击链接“插入”(您可以单击“删除”以删除所有以前的插入)。您必须在本地控制台上看到一条包含已添加项目的消息。
  3. 关闭计算机上的无线并再次单击插入链接。 (您需要点击另一台可以上网的电脑,我使用智能手机点击链接)
  4. 打开计算机上的无线。您必须在本地控制台上看到一条包含第二项的消息。
  5. 现在,关闭电缆调制解调器并再次单击插入链接。
  6. 打开电缆调制解调器。这次,新项目没有出现在控制台上。

我还使用 Android 智能手机使用通过无线方式将互联网共享到我的计算机的选项来完成此操作。首先,我关闭并打开计算机上的无线网络并正常工作。然后我关闭并打开智能手机上的互联网连接,我遇到了同样的问题。

Update 2

我的办公室有两个无线路由器。我发现如果我在路由器之间移动也会发生同样的问题。


来自 Meteor 团队的 Emily Stark 确认这是由于当前实现(我写此答案时版本为 0.7.0.1)缺少功能所致。他们的答案就在这里https://github.com/meteor/meteor/issues/1543。以下是他们的答案和她建议的解决方法:

服务器到服务器的连接不会重新连接,因为 Meteor 目前不对服务器到服务器的 DDP 连接执行任何检测信号。就像在任何其他 TCP 连接中一样,一旦切换到不同的路由器,连接上就无法发送或接收任何数据,但客户端不会注意到,除非它尝试发送一些数据并超时。这与在 SockJS 上运行的浏览器到服务器 DDP 连接不同。 SockJS 有自己的心跳,我们可以用它来检测死连接。

要查看此操作的实际效果,以下是我在示例中添加到 server-b 的一些代码:

var heartbeatOutstanding = false;
Meteor.setInterval(function () {
  if (! heartbeatOutstanding) {
   console.log("Sending heartbeat");
    remote.call("heartbeat", function () {
      console.log("Heartbeat returned");
      heartbeatOutstanding = false;
    });
    heartbeatOutstanding = true;
  }
}, 3000);

remote.onReconnect = function () {
  console.log("RECONNECTING REMOTE");
};

添加此代码后,服务器 b 将在经过足够长的时间后重新连接,而服务器 a 不会对传递心跳方法调用的 TCP 段发出 ACK。在我的机器上,这只需几分钟,我会收到一个 ETIMEDOUT 消息,然后重新连接。

我已经为我们打开了一个单独的任务,让我们考虑在下一个错误周期间在服务器到服务器 DDP 连接上实现检测信号。同时,您始终可以在应用程序中实现检测信号,以确保在客户端无法再与服务器通信时发生 DDP 重新连接。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

两台服务器之间的 DDP 不会重新连接 的相关文章

随机推荐

  • javascript中删除小数点后的数字

    var randomNumber Math random 3 3 5 randomNumber alert randomNumber 这段代码返回一个数字 例如 4 589729345235789 我需要它返回 4 5 因此需要它删除小数点
  • 多语言站点,子目录作为语言(RewriteRule)

    对于我的网站 我想将我的网址重写为 www xxx com en index php 而不是 www xxx com index php language enwww xxx com nl index php 而不是 www xxx com
  • 今天全日历开始日期

    我正在努力从今天开始制定完整的日历 当我这样做时 它会显示整周 calendar fullCalendar Options calendar fullCalendar gotoDate currentDate 其中 currentDate
  • 内存数据库的概念以及如何查看我的数据是否已填充到 HSQL DB 中?

    我在内存数据库中使用 HSQL 来测试我的应用程序 并使用 SQL Server 作为主数据库 现在在进行测试时 HSQL 数据库将填充与我在 SQL Server 中相同的数据 现在我正在尝试测试特定的数据从数据库检索数据的服务 如果直接
  • sql 从函数或存储过程返回表

    这更多的是一个语法问题 我正在尝试编写一个可以嵌入到查询中的存储过程或函数 例如 select from MyBigProcOrFunction 我正在尝试定义一个表格函数 但我不明白如何执行此操作 因为我构建临时表来计算数据 然后才最终在
  • 选择最近 7 天的最大值

    我通过每小时插入描述这些项目的记录作为 cron 作业来跟踪某些项目 我有一张桌子 steamid int eventid auto increment itemid int value int time unix format 我使用每小
  • AWS部署经常出现故障

    因此 我在 EC2 实例上进行了非常基本的部署 除了几个大问题外 该部署基本上可以正常工作 现在我只是通过 ssh 进入盒子并运行 python m SimpleHTTPServer 80 我在安全组上有一个框 允许端口 80 上的 htt
  • 在 SQL Server Management Studio 中执行 NHibernate 生成的准备好的语句

    配置 NHibernate 以显示执行的 SQL 可以完成预期的任务 但是每当需要将 SQL 字符串复制粘贴到 SQL Server Management Studio 中时 我们就必须对其进行大幅重新排列才能兼容 在我开始开发自己的应用程
  • 与下一行、分组、data.table 进行比较

    我有一个数据框 其中包含每个用户每周的页面浏览量 我想确定每个用户在特定事件发生后他们的观点是否增加 减少或保持不变 我的数据如下所示 Userid week xeventinweek numviews Alice 1 2 5 Alice
  • 如何用StepVerifier验证提供的Mono没有完成?

    With StepVerifier很容易检查是否提供Mono已完成 仅通过expectComplete 中的方法StepVerifier 但是如果需要检查相反的情况该怎么办 我尝试使用这种方法 Test public void neverM
  • 使用 Glide 和 FireBase android 存储和显示图像

    我正在尝试使用 Glide 和 Firebase 上传并显示个人资料图片 上传部分工作成功 但是 如果我尝试从数据库加载该图像 它会显示空白 我的动机是在用户进入活动一次时加载 profile image 他可以点击现有图像并根据自己的意愿
  • 如何在 TeamCity 中构建 Delphi 项目

    我正在尝试在 TeamCity 中构建一个 delphi 项目 但无法让它工作 我正在使用 MSBuild 来构建项目 并且还向构建添加了 BDS 参数 但我不断收到错误 MSB4040 项目中没有目标 您需要注意几件事 首先 需要设置De
  • 运行导出 apk 时出现“java.lang.ClassNotFoundException”错误

    我在 Eclipse 中编写了一个 Android 应用程序 并在手机上使用运行命令 在我的手机上运行成功 但我使用 Android Tools gt Export Signed Application Package 导出我的应用程序 然
  • Go 中独特函数的集合

    我正在尝试在 go 中实现一组功能 上下文是一个事件服务器 我想防止 或至少警告 为一个事件多次添加相同的处理程序 我读过 地图通常用作集合 因为可以轻松检查成员资格 if ok set item ok don t add item els
  • 在 PKCS7 (CMS) 中使用相同的响应 xml 签名对多个位置进行签名

    PDF 文档需要使用国家数字身份进行签名 国家数字身份WebService提供了签署文档的设施 在我的项目中我已经集成了相同的设施 请求设计服务给出响应PKCS7 CMS 格式 我想在多个位置附加相同的响应 因此我在收到来自服务的响应后创建
  • C# 创建缩略图(低质量和大尺寸问题)

    public void CreateThumbnail Image img1 Photo photo string targetDirectoryThumbs int newWidth 700 int newHeight 700 doubl
  • 包含头文件时,路径区分大小写吗?

    给定这个目录树 src MyLibrary MyHeader h src file cpp file cpp include mylibrary myheader h 在 VS 中编译 file cpp 可以 在 gcc 中编译失败 标准怎
  • 防止未经授权的成员加入 Hazelcast 集群

    我们正在更改我们的一个应用程序以使用 Hazelcast 3 11 Community Edition 并在一些主机上运行的多个 JVM 之间进行一些锁定 我们按照语法配置集群 如下所示 public class HazelcastBuil
  • 获取JavaFX中节点的高度(生成布局通道)

    如何在JavaFX中获取节点的高度或首选高度 我有3VBox我想将节点添加到最自由的面板 例如 Childrens Total Height of the children s Sum VBoxA 5 890 VBoxB 4 610 VBo
  • 两台服务器之间的 DDP 不会重新连接

    我有两个流星应用程序通过不同服务器上的 DDP 连接 服务器 A 将数据发送到服务器 B 这就是它们的工作方式 Server A Items new Meteor Collection items Items insert name ite