Sandbox →
Nu a fost o zi liberă, și m-am decis să joace în jurul valorii cu biblioteca Google :: Protobuf. Această bibliotecă oferă posibilitatea de a codifica și decodifica date structurate. Pe baza acestei biblioteci, am construi un controler de simplu, care poate ocupa orice mesaj. Singularitatea acestui controler este că el nu va ști tipurile de mesaje care trebuie transmise, și va procesa doar mesaje cu ajutorul stivuitoare înregistrate.
SCURTĂ DESCRIERE Biblioteca Protobuf
Deci, mai întâi o scurtă privire la biblioteca Google :: Protobuf, este furnizat ca două componente:
De fapt, fișierele antet bibliotecă +
Fișier compilatoare * .proto - genera descrierea de posturi A ++ clasa C (așa cum este posibil să se genereze pentru alte limbaje de programare: Java, Python, etc)
Un fișier separat este creat o descriere a mesajului, din care va fi generat clasa, sintaxa este foarte simplu:
Aici, vom descrie mesajul ServerStatusAnswer care are două câmpuri opționale:
- THREADCOUNT - întreg ca parametru opțional
- ascultători - un șir opțional care poate fi repetată de mai multe ori
În format Protobuf fapt - un binar, aici am aduce un mesaj într-un format care poate fi citit numai pentru claritate
Compilatorul generează automat cod C ++ pentru serializarea și deserializarea de astfel de mesaje. Protobuf bibliotecă oferă, de asemenea caracteristici suplimentare: serializare într-un fișier, un curent într-un tampon.
Eu folosesc CMake ca sistem de construcție, și are deja sprijinul Protobuf:
PROTOBUF_GENERATE_CPP - acest macro provoacă un compilator pentru fiecare fișier protoc * .proto și generează fișierele și h corespunzătoare CPP-ului care sunt adăugate la ansamblul.
Totul se face automat, și nici o suplimentare abdomene nu trebuie să (sub * nix ar putea avea nevoie de un pachet adițional de fire și un agent de legătură de pavilion).
Descriere manager de
Am decis să încerc să scrie un manager de mesaj, care are un mesaj, solicită handler adecvat și trimite un răspuns la mesajul primit. În acest caz, operatorul nu cunoaște tipurile de mesaje transmise lui. Acest lucru poate fi necesar în cazul în care controlerul adaugă sau șterge stivuitoare corespunzătoare în timpul funcționării (de exemplu, încărcați un model de expansiune corespunzătoare, * .dll * .so).
Ea vine vorba de salvare a spune: „Orice problemă poate fi rezolvată prin introducerea unui nivel suplimentar de abstractizare, ci o problemă de prea multe nivele de abstractizare“
Trebuie să se separe definiția tipului de mesaj din mesajul în sine, o putem face în felul următor:
Ne vom împacheta mesajul într-un alt mesaj:
- ID-ul câmp obligatoriu oferă un identificator unic mesaj
- câmp de date opțional conține mesajul nostru
Dar acum vedem că fiecare handler trebuie să efectueze eșantion posturi de decompresie :: proto :: Mesaj în propriul mesaj. Și acest proces va fi duplicată pentru fiecare dintre handler. Dorim să evite duplicarea de cod, astfel încât să ia modelul de tip Erasure. Acest model vă permite să ascundeți tipul de entitate care urmează să fie tratat pentru o interfață comună, dar fiecare procesor va lucra cu un anumit tip, cunoscut doar de el.
Astfel, punerea în aplicare este foarte simplu:
Definim procesul de functii virtuale. dar, de asemenea, adăuga o doProcess funcție virtuală. care este deja de lucru cu mesajele noastre specifice. Această tehnică se bazează pe mecanismul de șablon instanțierea: tipuri sunt introduse în momentul utilizării efective a șablonului, mai degrabă decât la momentul declarației. Din moment ce această clasă moștenește de la MessageProcessorBase, atunci putem transmite în siguranță moștenitorii acestei clase managerului nostru. De asemenea, trebuie remarcat faptul că această clasă oferă serializarea și deserializarea mesajele noastre specifice și aruncă o excepție în cazul în care apar erori.
Și, în sfârșit, aici este un exemplu de utilizare a acestui controler, să spunem că avem două tipuri de mesaje:
După cum se poate observa din descrierea - datele solicitate de mesaje de la serverul de starea sa internă (ServerStatus), și pur și simplu returnează interogarea (Echo). Stivuitoare de implementare în sine triviale, voi doar implementarea ServerStatus:
Punerea în aplicare în sine:
Iată cum funcționează:
- gcc-4.4.5-linux
- cmake-2.8.2
- stimula-1,42
- Protobuf-2.3.0
EXEMPLUL pus pe GitHub