Meteor 两台服务器之间的DDP不';t重新连接

Meteor 两台服务器之间的DDP不';t重新连接,meteor,Meteor,我有两个meteor应用程序通过DDP连接在不同的服务器上,服务器A向服务器B发送数据。这就是它们的工作方式 服务器A Items=newmeteor.Collection('Items'); 插入({name:'item 1'}); if(Meteor.isServer){ Meteor.publish('items',function()){ 返回Items.find(); }); } 服务器B var remote=DDP.connect('http://server-a/'); 项目=

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

服务器A

Items=newmeteor.Collection('Items');
插入({name:'item 1'});
if(Meteor.isServer){
Meteor.publish('items',function()){
返回Items.find();
});
}
服务器B

var remote=DDP.connect('http://server-a/');
项目=新的Meteor.Collection(“项目”,远程);
远程订阅(“项目”);
Items.find().观察({
新增:功能(项){
控制台日志(项目);
}
});
每次我调用
Items.insert(something)
在服务器A上,在服务器B上,我都会在控制台上获得一个日志,其中包含我保存在服务器A上的对象。但是,如果服务器B失去了Internet连接,则服务器A上插入的数据在重新连接到Internet时不再显示在服务器B上

服务器B通过路由器连接到Internet。此问题仅在断开并重新连接路由器时发生,而不是在断开并重新连接服务器与路由器时发生。两台服务器都位于不同的网络上,并通过Internet连接

我在服务器B上创建了一个计时器,它调用
remote.status()
,但在连接或断开Internet时总是获取
{status:'connected',connected:true,retryCount:0}

更新:复制步骤

我用测试代码在github上创建了一个项目。服务器A安装在上

我的电脑通过无线电缆调制解调器连接到互联网

  • 在服务器b文件夹上运行mrt
  • 转到并单击链接插入(可以单击“删除”删除所有以前的插入)。您必须在本地控制台上看到带有添加项的消息
  • 关闭计算机上的无线连接,然后再次单击“插入”链接。(你需要点击另一台可以上网的电脑,我用智能手机点击了链接)
  • 打开计算机上的无线网络。您必须在本地控制台上看到包含第二项的消息
  • 现在,关闭电缆调制解调器并再次单击“插入”链接
  • 打开电缆调制解调器。这一次,新项目不会出现在控制台上
  • 我还用安卓智能手机实现了这一点,它可以通过无线方式将互联网分享给我的电脑。首先,我关掉和打开电脑上的无线设备,工作正常。然后我关掉了智能手机的网络连接,我也遇到了同样的问题

    更新2


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

    我认为您没有正确地将DDP连接对象传递到集合,请尝试:

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

    首先从浏览器控制台尝试所有这些连接游戏可能对调试很有用,因为Meteor在客户端上提供了相同的连接/集合API(控制流除外)。只需打开任何Meteor应用程序,并从控制台尝试这句话。

    Meteor团队的Emily Stark确认,这是由于当前实现中缺少一个功能(我编写此答案时的版本为0.7.0.1)。他们的答案就在这里。以下是他们的答案和她建议的解决办法:

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

    要了解这一点,下面是我在您的示例中添加到server-b的一些代码:

    var=false;
    Meteor.setInterval(函数(){
    如果(!优秀){
    日志(“发送心跳”);
    远程调用(“心跳”,函数(){
    log(“返回心跳”);
    心脏跳动=假;
    });
    心碎=真实;
    }
    }, 3000);
    remote.onReconnect=函数(){
    控制台日志(“重新连接远程”);
    };
    
    在那里添加了这段代码后,服务器b将在足够长的时间之后重新连接,而服务器a不会对正在传递heartbeat方法调用的TCP段发出ACK。在我的机器上,这只是几分钟,我得到一个ETIMEDOUT,然后重新连接


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

    我根据camilosw的代码修改了两个DDP服务器之间的通信示例

    服务器A作为云数据中心。服务器B作为数据源,如果某些数据发生更改,则应发送到服务器A


    您可以从

    中找到代码,显然这两种方法的工作原理相同。我试过你的代码,但它没有解决问题。那么我只能建议发布一个复制品。服务器到服务器ddp是我们每天在Meteor DG内部使用的东西。值得注意的是,Galaxy几乎在任何地方都依赖于服务器到服务器的ddp,所以我认为它不可能被遗忘或过时。感谢您对imslavko的支持。我用更多的细节更新了我的问题。这可能与该问题有关。这是我在github上打开的问题的副本。很抱歉,我随机发现了它,并认为它会相关。没有看真名。是的,很抱歉我的回答没有任何帮助,事实上,这是应该用某种心跳来解决的问题。