Pour le dire simplement, le serveur publie continuellement des messages et le client recevra les messages après s'être abonné.
Ici, nous regardons une force simple:
Serveur:
#include <stdlib.h> #include <zmq.h> #include < string .h> #include <unistd.h> #include <time.h> #define buffersize 4096 #define randof (num) (int) ((() float) (num) * random () / (RAND_MAX + 1.0)) int main ( int argc, char * argv []) { // [0] 创建 对象void * ctx = zmq_ctx_new (); void * publisher = zmq_socket (ctx, ZMQ_PUB); // [1] 到 到 5566 端口 zmq_bind (éditeur, " tcp: // *: 5566 " ); // 初始化 随机 数 生成 器 srandom (temps (non signé) (NULL)); while ( 1 ) { int code postal, température, relhumidité; code postal = randof ( 100000 ); température = randof ( 215 ) - 80 ; relhumidité = randof ( 50 ) + 10 ; // Envoie un message à tous les abonnés char update [ 20 ]; sprintf (mise à jour, " % 05d% d% d " , code postal, température, relhumidité); printf ( " envoi serveur:% s \ n " , mise à jour); // s_send (éditeur, mise à jour); zmq_send (éditeur, mise à jour, strlen (mise à jour), 0 ); sommeil ( 1 ); } zmq_close (éditeur); zmq_ctx_destroy (ctx); retourner 0 ; }
Client:
#include <stdlib.h> #include <zmq.h> #include < string .h> #include <unistd.h> #include <time.h> #include <assert.h> char statique * s_recv ( void * socket ) { carbonisation tampon [ 256 ]; int size = zmq_recv (socket, buffer, 255 , 0 ); if (size == - 1 ) return NULL; tampon [taille] = ' \ 0 ' ; revenir strndup (buffer, sizeof (buffer) -1 ); } int main ( int argc, char * argv []) { // [0] Créez un objet et connectez-vous au port 5566 printf ( " Collecte des mises à jour du serveur météo ... \ n " ); void * context = zmq_ctx_new (); void * subscriber = zmq_socket (context, ZMQ_SUB); int rc = zmq_connect (subscriber, " tcp: // localhost: 5566 " ); assert (rc == 0 ); / / [1] Définissez les conditions de filtrage, définies sur vide, ce qui signifie un abonnement complet, où "1" correspond aux données commençant par "1" const char * filter = " 1 " ; rc = zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, filter, strlen (filter )); assert (rc == 0 ); // [2] accepte les données int update_nbr; long total_temp = 0 ; for (update_nbr = 0 ; update_nbr < 100 ; update_nbr ++ ) { char * string = s_recv (abonné); printf ( "client:% s \ n " , chaîne ); int code postal, température, relhumidité; sscanf ( chaîne , " % d% d% d " , & code postal, & température, & relhumidity); total_temp + = température; libre ( chaîne ); } printf ( " La température moyenne pour le code postal '% s' était% dF \ n " , filtre, ( int ) (total_temp / update_nbr)); zmq_close (abonné); zmq_ctx_destroy (context); retourner 0 ; }
en dehors:
// serveur envoi serveur: 43345 - 41 19 envoi serveur: 44203 110 59 envoi serveur: 78038 2 25 envoi serveur: 55377 59 18 envoi serveur: 40135 - 65 36 envoi serveur: 37950 43 10 // client zf @ eappsvr- 0 : ~ / ds / zmq / test / pub_sub> ./ client Collecte des mises à jour à partir du serveur météo ... client .... client: 10057 67 11 client:16839 94 25
Remarque:
Il convient de noter que lorsque vous utilisez un socket SUB, vous devez utiliser la méthode zmq_setsockopt () pour définir le contenu de l'abonnement. Si vous ne configurez pas de contenu d'abonnement, vous ne recevrez aucune nouvelle, et il est facile pour les novices de commettre cette erreur. Les informations d'abonnement peuvent être n'importe quelle chaîne et peuvent être définies plusieurs fois. Tant que le message satisfait l'une des informations d'abonnement, le socket SUB sera reçu. L'abonné peut choisir de ne pas recevoir certains types de messages, ce qui est également obtenu par la méthode zmq_setsockopt ().
La combinaison de connecteurs PUB-SUB est asynchrone. Le client utilise zmq_recv () dans un corps de boucle pour recevoir le message. S'il envoie un message au socket SUB, une erreur sera signalée; de même, le serveur peut utiliser en continu zmq_send () pour envoyer le message, mais il ne peut pas être utilisé sur le socket PUB. zmq_recv ().
Une dernière chose à noter sur les sockets PUB-SUB: vous ne pouvez pas savoir quand SUB a commencé à recevoir des messages. Même si vous ouvrez d'abord le socket SUB, puis ouvrez le PUB pour envoyer des messages, SUB perdra quand même certains messages, car l'établissement de la connexion prend un certain temps. Très peu, mais pas zéro.