2013-10-25 4 views
2

У меня есть два приложения метеора, подключаемые через DDP на разных серверах и серверах. Передача данных на сервер B. Это то, как они работают.DDP между двумя серверами не соединяется

Сервер

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); 
    } 
}); 

Каждый раз, когда я называю Items.insert(something) на сервере А, на сервер BI получил журнал на консоли с объектом я сэкономил на сервере А. Но если сервер B потерял подключение к Интернету, данные, вставленные на сервер A, больше не отображаются на сервере B при повторном подключении к Интернету.

Сервер B подключен к Интернету через маршрутизатор. Эта проблема возникает только при отключении и повторном подключении маршрутизатора, а не при отключении и повторном подключении сервера к маршрутизатору. Оба сервера находятся в разных сетях и подключаются через Интернет.

Я создал таймер на сервере B, который вызывает remote.status(), но всегда получает { status: 'connected', connected: true, retryCount: 0 } при подключении или отключении от Интернета.

Update: шаги для воспроизведения

Я создал проект на GitHub с кодом тестирования https://github.com/camilosw/ddp-servers-test. Сервер A установлен на http://ddpserverstest-9592.onmodulus.net/

Мой компьютер подключен к Интернету через беспроводной кабельный модем.

  1. Run MRT на сервер-б папку
  2. Перейти к http://ddpserverstest-9592.onmodulus.net/ и нажмите на ссылку Insert (вы можете нажать кнопку Удалить, чтобы удалить все предыдущие вставки). Вы должны увидеть сообщение на своей локальной консоли с добавленным элементом.
  3. Выключите беспроводную сеть на компьютере и снова нажмите ссылку на вставку. (Вам нужно будет щелкнуть на другом компьютере с доступом в Интернет, я использовал смартфон, чтобы щелкнуть ссылку)
  4. Включите беспроводную сеть на компьютере. Вы должны увидеть сообщение на своей локальной консоли со вторым элементом.
  5. Теперь выключите кабельный модем и снова нажмите ссылку на вставку.
  6. Включите кабель-модем. На этот раз новый элемент не появится на консоли.

Я также сделал это с помощью Android-смартфона, используя возможность совместного доступа к Интернету на свой компьютер через беспроводную сеть. Сначала я отключился и включил беспроводную связь на своем компьютере и работал правильно. Затем я отключился и подключился к Интернету на смартфоне, и у меня такая же проблема.

Update 2

У меня есть два беспроводных маршрутизатора на моем офисе. Я обнаружил, что такая же проблема возникает, если я перемещаюсь между маршрутизаторами.

+0

это может быть связано с https://github.com/meteor/meteor/issues/1724 – imslavko

+0

Эта проблема является дубликатом проблемы, которую я открыл на github https://github.com/meteor/meteor/issues/1543 – Camilo

+0

О, я сожалею, случайно нашел это и подумал, что это будет связано. Не смотрел на настоящие имена. Да, извините за мой ответ, который не помог вообще, на самом деле это то, что нужно решать с помощью каких-то сердечных сокращений. – imslavko

ответ

3

Эмили Старк из команды Meteor подтвердила, что это связано с отсутствием функции в текущей реализации (версия 0.7.0.1 на данный момент я пишу этот ответ). Их ответ здесь https://github.com/meteor/meteor/issues/1543. Ниже приведен их ответ и обходное решение, которое она предлагает:

Соединение между серверами не пересоединяется, потому что в настоящее время Метеор не делает никаких попыток подключиться к серверным соединениям DDP. Как и в любом другом TCP-соединении, как только вы переключаетесь на другой маршрутизатор, никакие данные не могут быть отправлены или получены в соединении, но клиент не заметит, если он не попытается отправить некоторые данные и время. Это отличается от соединений DDP от сервера к серверу, которые работают через SockJS. SockJS делает свое собственное сердцебиение, которое мы можем использовать для обнаружения мертвых соединений.

Чтобы увидеть это в действии, вот код, который я добавил к серверу-б в вашем примере:

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"); 
}; 

с добавлением туда этот код, сервер-б будет восстановить после достаточно долго идет без ACK с сервера-a для сегментов TCP, которые выполняют вызов метода heartbeat. На моей машине это всего лишь пару минут, и я получаю ETIMEDOUT, за которым следует повторное подключение.

Я открыл для себя отдельную задачу подумать о том, как внедрить сердцебиение на соединения между серверами DDP во время нашей следующей недели ошибок. В то же время вы всегда можете выполнять биение в своем приложении, чтобы обеспечить повторное соединение DDP, если клиент больше не может разговаривать с сервером.

1

Я думаю, вы не передавая объект подключения DDP к сборнику правильно, попробуйте:

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

Это может быть полезно для отладки, чтобы попробовать все эти соединения игры с консоли браузера первой, так как метеор предоставляет те же API соединения/коллекций на клиенте (кроме потока управления). Просто откройте любое приложение Meteor и попробуйте эти строки с консоли.

+0

Очевидно, что оба пути работают одинаково. Я пробовал ваш код, но он не решает проблему. – Camilo

+0

Тогда я не могу предложить ничего, кроме публикации репродукции. Сервер-сервер ddp - это то, что мы используем в Meteor DG каждый день. Примечательно, что Galaxy полагается на сервер-сервер ddp почти везде, поэтому я предполагаю, что он не был забыт или устарел. – imslavko

+0

Спасибо за вашу поддержку imslavko. Я уточнил свой вопрос более подробно. – Camilo

0

Я пересмотрел образец связи между двумя серверами ddp, основанными на коде Camilosw.

Сервер A в качестве облачного центра обработки данных. Сервер B в качестве источника данных, если некоторые данные изменились, следует отправить на сервер А.

Вы можете найти код от https://github.com/iascchen/ddp-servers-test

Смежные вопросы