Ten rodzaj centrali wiadomości jest ulepszoną wersją centrali wiadomości bezpośrednich. Zasadniczą zmianą jest wykorzystanie nagłówków zamiast kluczy routing’u.
Każdy nagłówek ma dwie cechy:
Z tego też powodu zamiast używać kluczy routing’u, które mogły być tylko łańcuchami znaków, można użyć np. liczb całkowitych lub funkcji skrótu (ang. hash) na bazie słownika.
Lista nagłówków może wyglądać następująco:
Nazwa | Wartość |
---|---|
x-match | any |
type | error |
app | node.js |
host | 10.0.0.15 |
Wyróżniamy dwa rodzaje sposobów dopasowania wiadomości do określonych filtrów w centralach z nagłówkami ustawiane jako argument dla parametru x-match:
Oba rodzaje dopasowania ilustrują dwa diagramy:
Jako bazowy kod weźmy kod programu fabryka.js, który w uproszczeniu wyglądał następująco:
#!/usr/bin/env node
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
// nowe instrukcje
});
setTimeout(function() { conn.close(); process.exit(0) }, 500);
});
Zanim zaczniemy pisać dwa nowe programy (nadawcę i odbiorcę), potrzebujemy określić co one będą dla nas robić?
Przypuśćmy, że nadawca przesyła nam z portalu randkowego:
Natomiast odbiorca będzie miał ustawione „na sztywno” pożądane cechy drugiej połówki, tzn. w kodzie będzie zaszyte, jaką płeć i jaki kolor włosów swojej wybranki/wybranka preferuje.
Zacznijmy od aplikacji serwisu randkowego, który będzie wysyłał „profile” do systemu RabbitaMQ. Nazwijmy go randkoder.js
Tuż po zaimportowaniu biblioteki amqplib definiujemy sposób korzystania z naszego nadawcy:
#!/usr/bin/env node
var amqp = require('amqplib/callback_api');
var args = process.argv.slice(2);
var numberOfArguments = 3;
var numberOfAttributes = 2;
if (args.length !== numberOfArguments) {
console.log("Korzystanie: randkoder.js [imię] [płeć: k|m] [kolor włosów: blond|rude|siwe|czarne]");
console.log(" randkoder.js Karolina k blond");
process.exit(1);
}
amqp.connect('amqp://localhost', function(err, conn) {});
W zmiennej numberOfAttributes ustaliliśmy, że będziemy podawać trzy cechy konkretnej osoby z portalu randkowego, czyli imię, płeć oraz kolor włosów.
Wywołanie programu z inną liczbą parametrów spowoduje wyświetlenie odpowiedniego komunikatu na konsoli.
Wartości podane do programu mogą być dowolne, jednak aby pomóc użytkownikowi w korzystaniu z programu, dostarczamy mu przykładowe dane, np. rudy kolor włosów. Nie definiujemy oddzielnego słownika, aby program był jak najprostszy.
W sekcji do uzupełnienia najpierw definiujemy nazwę centrali:
var ex = 'randkomierz';
Następnie pobieramy cechy kandydatki/kandydata:
var args = process.argv.slice(2);
var name = args[0];
var attributes = args.slice(1);
Potem definiujemy klucze dla naszych nagłówków odpowiadających przekazywanym do programu cechom:
var headersList = ['plec', 'kolor-wlosow'];
oraz wypełniamy nagłówki wartościami:
var headersValues = {};
for (var i=0; i<numberOfAttributes; i++) {
var headerName = headersList[i];
var headerValue = attributes[i];
headersValues[headerName] = headerValue;
}
Na koniec wysyłamy wiadomość do kuriera wiadomości:
ch.assertExchange(ex, 'headers', {durable: false});
ch.publish(ex, '', new Buffer(name), {headers: headersValues});
console.log(" [x] Wysłano profil '%s'", name);
Kompletny program randkoder.js wygląda następująco:
#!/usr/bin/env node
var amqp = require('amqplib/callback_api');
var args = process.argv.slice(2);
var numberOfArguments = 3;
var numberOfAttributes = 2;
if (args.length !== numberOfArguments) {
console.log("Korzystanie: randkoder.js [imię] [płeć: k|m] [kolor włosów: blond|rude|siwe|czarne]");
console.log(" randkoder.js Karolina k blond");
process.exit(1);
}
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
var ex = 'randkomierz';
var args = process.argv.slice(2);
var name = args[0];
var attributes = args.slice(1);
var headersList = ['plec', 'kolor-wlosow'];
var headersValues = {};
for (var i=0; i<numberOfAttributes; i++) {
var headerName = headersList[i];
var headerValue = attributes[i];
headersValues[headerName] = headerValue;
}
ch.assertExchange(ex, 'headers', {durable: false});
ch.publish(ex, '', new Buffer(name), {headers: headersValues});
console.log(" [x] Wysłano profil '%s'", name);
});
setTimeout(function() { conn.close(); process.exit(0) }, 500);
});
Pozostało nam już tylko użyć napisanego „randkodera”:
Terminal1 $ ./randkoder.js Miłosława k czarne
[x] Wysłano profil 'Miłosława'
Terminal1 $ ./randkoder.js Anna k rude
[x] Wysłano profil 'Anna'
Gdy mamy już program nadawcy, pora zabrać się za program swatka.js, który będzie odfiltrowywał nam profile, którymi nie jesteśmy zainteresowani, a wyłapywał tylko te najciekawsze w oparciu o zdefiniowane przez nas cechy.
Ponieważ program nie jest skomplikowany, możemy przejść do analizy od razu całego kodu:
#!/usr/bin/env node
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
var ex = 'randkomierz';
ch.assertExchange(ex, 'headers', {durable: false});
ch.assertQueue('', {exclusive: true}, function(err, q) {
console.log(' [*] Oczekiwanie na wiadomości w:');
console.log(' %s', q.queue);
console.log(" Naciśnij CTRL+C aby zakończyć.");
ch.bindQueue(q.queue, ex, '', {
'x-match': 'all',
'plec': 'k',
'kolor-wlosow': 'czarne'
});
ch.consume(q.queue, function(msg) {
console.log(" [x] '%s' pasuje do Ciebie", msg.content.toString());
}, {noAck: true});
});
});
});
Definiujemy tutaj centralę wiadomości z nagłówkami o tej samej nazwie co w programie nadawcy – „randkoder”, a następnie podpinamy do niej kolejkę, wskazując interesujące nas cechy.
W centralach z nagłówkami nie używamy kluczy routing’u, zatem w ich miejsce podajemy pusty łańcuch.
W powyższym przykładzie zastosowano dopasowanie „all”, dzięki czemu możemy lepiej zobaczyć, jak program działa z konkretnymi danymi.
Teraz, gdy uruchomimy program swatka.js, będziemy mogli zobaczyć, jak działa nasze filtrowanie:
$ ./swatka.js
[*] Oczekiwanie na wiadomości w
amq.gen-z3KMAIo8WpAW72DaFdqc5w
Naciśnij CTRL+C, aby zakończyć.
[x] 'Miłosława' pasuje do Ciebie
Nic nie stoi na przeszkodzie, aby zmienić tę opcję na „any”:
$ ./swatka.js
[*] Oczekiwanie na wiadomości w
amq.gen-z1KRAIo8WpAW72DaFdqd3z
Naciśnij CTRL+C, aby zakończyć.
[x] 'Miłosława' pasuje do Ciebie
[x] 'Anna' pasuje do Ciebie
Centrale komunikatów typu headers można stosować przy obsłudze:
Kod programów omawianych w tym tutorialu znajduje się pod adresem:
https://github.com/RattiQue/tutorials-pl-node.js
Web Developer z ponad 8-letnim, komercyjnym doświadczeniem w tworzeniu stron i aplikacji internetowych oraz paneli administracyjnych w PHP, JavaScript, HTML i CSS.
Aktualnie zainteresowany architekturą mikroserwisów, które umożliwiają budowanie skalowalnych aplikacji internetowych.