我有两个通过DDP连接在不同服务器上的流星应用程序,服务器A将数据发送到服务器B.这就是它们的工作方式。
服务器A
Items = new Meteor.Collection('items');
Items.insert({name: 'item 1'});
if (Meteor.isServer) {
Meteor.publish('items', function() {
return Items.find();
});
}
服务器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);
}
});
每次我在服务器A上调用Items.insert(something)
时,在服务器BI上都会在控制台上记录我在服务器A上保存的对象。但是如果服务器B丢失了Internet连接,则在服务器A上插入的数据不会当服务器B重新连接到Internet时,它将再次出现在服务器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/
上我的电脑通过无线电缆调制解调器连接到互联网。
我也使用Android智能手机使用选项通过无线方式将Internet共享到我的电脑。首先,我关闭了计算机上的无线网络并正常工作。然后我关闭了智能手机上的互联网连接,我遇到了同样的问题。
更新2
我的办公室里有两个无线路由器。我发现如果我在路由器之间移动会发生同样的问题。
答案 0 :(得分:3)
服务器到服务器的连接没有重新连接,因为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");
};
在此处添加了此代码后,server-b将在经过足够长的时间后重新连接,而不会发送来自服务器的ACK-a用于提供心跳方法调用的TCP段。在我的机器上,这只是几分钟,我得到一个ETIMEDOUT,然后重新连接。
我已经开设了一个单独的任务,让我们考虑在下一个bug周期间在服务器到服务器DDP连接上实现心跳。与此同时,您可以始终在应用程序中实现心跳,以确保在客户端无法再与服务器通信时发生DDP重新连接。
答案 1 :(得分:1)
我认为您没有正确地将DDP连接对象传递给Collection,请尝试:
var remote = DDP.connect('http://server-a/');
Items = new Meteor.Collection('items', { connection: remote });
调试首先从浏览器控制台尝试所有这些连接游戏可能很有用,因为Meteor在客户端上提供了相同的连接/集合API(控制流除外)。只需打开任何Meteor应用程序,然后从控制台尝试这一行。
答案 2 :(得分:0)
我根据camilosw的代码修改了两个ddp服务器之间的通信示例。
服务器A作为云数据中心。服务器B作为数据源,如果某些数据发生了变化,应该发送到服务器A.
中找到代码