Właściwie nie jest to trudne.
Przede wszystkim musisz zdefiniować protokół, który ma być użyty. To może być bardzo proste; jak tylko pole typu komunikatu, pole rozmiaru ładunku i rzeczywisty ładunek. Typy wiadomości, których potrzebujesz: SUBSCRIBE
, UNSUBSCRIBE
i PUBLISH
. Ładunek dla wiadomości SUBSCRIBE
i UNSUBSCRIBE
to nazwa kanału, z którego subskrybujesz/rezygnujesz z subskrypcji. Ładunek dla wiadomości PUBLISH
to nazwa kanału i rzeczywiste dane (wraz z rozmiarem danych oczywiście).
Do połączenia wszystkich subskrybentów potrzebny jest serwer centralny. Wszyscy subskrybenci/wydawcy muszą połączyć się z tym serwerem. Program serwera przechowuje kolekcję kolejek, po jednej dla każdego kanału. Gdy wiadomość subskrybowana lub publikowana zostanie dostarczona do serwera dla kanału, który nie istnieje, utwórz nową kolejkę komunikatów dla tego kanału. Dla każdego kanału serwer potrzebuje również kolekcji wszystkich klientów subskrybujących ten kanał. Gdy wiadomość do opublikowania dotrze do serwera, zostanie dodana na końcu kolejki dla danego kanału. Chociaż kolejka kanałów nie jest pusta, wyślij jej kopię wszystkim subskrybentom tego kanału, a gdy wszyscy ją otrzymają, wiadomość może zostać usunięta z kolejki.
Najtrudniejszą częścią serwera będzie prawdopodobnie część komunikacyjna. Łatwa część będzie wszystkie kolejki i zbiory, jak można użyć C++ standard containers dla wszystkich z nich (np std::queue
dla rzeczywistej kolejce std::unordered_map
dla kanałów i std::vector
do zbierania powiązanych klientów).
Klienci są bardzo proste, wszystko co musisz zrobić, to móc wysyłać subskrypcje i publikować wiadomości na serwer, a także odbierać wiadomości publikowania z serwera. Najtrudniejsza część znów będzie faktyczną częścią komunikacji.
Postscriptum:
Nigdy faktycznie zbudowany taki system moje ja, wszystkie wyżej tylko bezpośrednio z górnej części głowy. Doświadczony programista nie powinien potrzebować więcej niż kilka godzin na wdrożenie podstaw, może kilka dni dla niedoświadczonego.
Do komunikacji można użyć np. Boost ASIO, może użyć jednego kanału threads. Możesz użyć czegoś takiego, jak Boost property tree do konstruowania/analizowania wiadomości: JSON lub XML.
Jednak to wszystko jest rodzajem ponownego wynajdywania koła, kiedy prawdopodobnie za kilka godzin można zacząć używać jednego z istniejących systemów, takich jak RabbitMQ, oszczędzając mnóstwo czasu (i wiele błędów!)
Czy potrzebujesz użyć biblioteki lub usługi? A może, biorąc pod uwagę warunki, wystarczy użyć gniazd lub rur? Byłoby to prawdopodobnie bardziej wydajne dla malin. –
ZeroMQ jest bardzo prosty w użyciu. – Kimi
@ dema80: Preferuję usługę, ale lib jest w porządku. Czy możesz zasugerować wykorzystanie gniazd użytkowych? – Yoshi