Запрос архитектуры. Создание шины службы/сообщений с помощью Node.js

Итак, ситуация такова, что у меня есть множество источников данных, которые обеспечивают поток сообщений с внешних устройств. Некоторые отправляют сообщения через последовательный порт, некоторые через UDP, некоторые через Telnet. Я хочу создать небольшой Node.js система, которая получает сообщения от каждого из этих источников. Всего около 20 источников.

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

Я думаю, вы могли бы назвать это «служебной шиной» или «шиной сообщений»..

На данный момент я просто обдумываю идеи о том, как его структурировать, мне не нужен один огромный файл node.js, который делает все.

Я хочу, чтобы каждый из «приемников» находился во внешних файлах .js в моем основном файле node.js. Мой подход ниже OK и есть ли какие-либо улучшения, которые я мог бы внести в свой подход.

Основной файл Node.js

Втягивает два «приемника». Каждый из них будет обрабатывать входящие сообщения из источника данных.

var sys = require("sys");

AVLReceiver = require("./avlreceiver.js").AVLReceiver();
PagerReceiver = require("./pagerreceiver.js").PagerReceiver();

pagerreceiver.js — пример получателя сообщений

Получает сообщения от последовательного порта.

var serialport = require("serialport");
var sys = require("sys");

var PagerReceiver = {};

PagerReceiver.initializePort = function () {
    this.serialport = new serialport.SerialPort("/dev/ttyS0", { 
        parser: serialport.parsers.readline("\n"), baudrate: 57600 
      });

    this.serialport.on("data", this.processMessage);
};

PagerReceiver.processMessage = function (data) {
  //deal with the message
};

PagerReceiver.initializePort();

exports.PagerReceiver = function() {
       return PagerReceiver;
};

Будет ли это подходящим способом разбить систему node.js? Любые комментарии к javascript также будут с благодарностью получены. Также любые комментарии о любых других архитектурных подходах, которые я должен рассмотреть для создания шины сообщений в node.js, были бы супер.

Спасибо за чтение,

Дункан.


person Duncan_m    schedule 12.03.2011    source источник
comment
С тех пор я нашел отличные уроки Педро Тейшейры, особенно о модулях Node.JS (nodetuts.com/tutorials/17-building-nodejs-modules.html#video), и я чувствую себя намного увереннее, продвигаясь вперед с этим подходом.   -  person Duncan_m    schedule 15.03.2011
comment
выглядит хорошо для меня, но имейте в виду, что вы создаете синглтон, что означает, что вы не можете создавать несколько экземпляров PagerReciever, если только с несколькими не требуется   -  person Amjad Masad    schedule 21.03.2011


Ответы (2)


Этому посту больше 8 лет, и проблема будет действительно решена; но я подумал, что могу поделиться некоторыми идеями с использованием современных Node и Typescript для всех, кто придет сюда.

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

Чистый способ приблизиться к этому — использовать выделенную служебную шину, например @node-ts/bus, который занимается всеми техническими сложностями повторной отправки сообщений, подписки на темы и т. д.

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

person Andrew dh    schedule 30.04.2019

Это старый вопрос, поэтому вы, вероятно, уже создали свое решение, но я добавлю свой взгляд на него на всякий случай, если он кому-то пригодится.

Идея изолирования вашего кода, специфичного для приемника, определенно кажется мне правильной, это даст читателю понять, какой код относится к основному рабочему процессу, а какой код относится к конкретному потоку.

У меня также возникло бы желание попробовать;

  • Если возможно, предоставьте всем своим приемникам одинаковый интерфейс, чтобы основной код был простым.
  • Возможно, используйте EventEmitters для запуска событий, которые могут быть перехвачены кодом приложения более высокого уровня.
  • Экстернализация конфигурации, такой как последовательные порты и скорости передачи данных, в файл конфигурации для каждого приложения или среды. Модульная система Node автоматически проверяет «~/node_modules», поэтому вы можете поместить туда конфигурацию для каждой среды, чтобы избежать перезаписи при развертывании нового кода.
  • У меня возникнет соблазн взглянуть на то, как ваш модуль экспортирует свою функциональность, см. ниже.

Экземпляр

Я считаю, что способ, которым вы занимаетесь созданием объекта, немного вводит в заблуждение, поскольку он делает exports.PagerReceiver() похожим на конструктор класса, которым он не является; в этом случае он возвращает одноэлементный объект. Сам модуль уже является одноэлементным экземпляром, поэтому это немного избыточно и может ввести в заблуждение.

Ниже приведен пример того, как несколько вызовов require() на самом деле ссылаются на одну и ту же приватную переменную i.

счетчик.js

var i = 0;

exports.iterate = function(){
    return i++;
};

test.js

var counter1 = require('./counter');
var counter2 = require('./counter');
console.log(counter1.iterate());
console.log(counter2.iterate());
console.log(counter1.iterate());
console.log(counter2.iterate());

выход:

0
1
2
3

Следующий код проще и функционально такой же, за исключением того, что он вызывается с помощью require() вместо require().PagerReceiver():

var serialport = require("serialport");
var sys = require("sys");

exports.processMessage = function (data) {
    //deal with the message
};

var port = new serialport.SerialPort("/dev/ttyS0", { 
    parser: serialport.parsers.readline("\n"), baudrate: 57600 
});

port.on("data", exports.processMessage);
person Richard Marr    schedule 22.05.2011
comment
Извините за поздний ответ, примите .. очень признателен. Хорошее понимание. Дункан. - person Duncan_m; 12.06.2011