基于ZeroMQ的聊天室设计实现

1.前言

最近一直在学习ZeroMQ的一些东东,越学越感觉ZeroMQ太强大了,索性自己也私下开始安排做些关于ZeroMQ的东西,只有这样才能够真正的体会到ZeroMQ的精髓,话不多说了,从今天开始准备每天或每两天写一个简单的ZeroMQ的小实例,也希望通过这些简单的小实例能够强化一些ZeroMQ理论知识,这个实例是我之前在大学时为了课程设计写过的课题报告,当时是做一个字符界面的聊天室,当时自己也是折腾的好久,这个Socket函数以及I/O事件的处理,于是我就随手选了它,看看用ZeroMQ来实现一个字符界面的聊天室到底有多简单,我选用的模式服务器端开启PULL模式和PUB的端口,而客户端开启的是PUSH模式和SUB的端口,话不多说,直接上代码

2. 服务器端代码

#include
#include
#include
#include
#include
#include
#define NAME_SIZE 64
#define BUFFER_SIZE 1024
int main(int argc,char** argv)
{
    if(argc < 3)
    {
        printf("syntax:%s  \n",argv[0]);
        exit(EXIT_SUCCESS);
    }
    void* context = zmq_init(1);
    assert(context);
    void* receiver = zmq_socket(context,ZMQ_PULL);
    void* publiser = zmq_socket(context,ZMQ_PUB);
    zmq_bind(receiver,argv[1]);
    zmq_bind(publiser,argv[2]);
    while(true)
    {   
        zmq_msg_t msg;
        zmq_pollitem_t items[] =
        {
            {receiver,0,ZMQ_POLLIN,0}
        };
        int rc = zmq_poll(items,1,-1);
        if(rc == -1)
            break;
        if(items[0].revents & ZMQ_POLLIN)
        {
            char receBuffer[BUFFER_SIZE];
            memset(receBuffer,0,sizeof(receBuffer));

            zmq_msg_init(&msg);
            zmq_msg_recv(&msg,receiver,0);
            memcpy(receBuffer,(char*)zmq_msg_data(&msg),zmq_msg_size(&msg
            zmq_msg_close(&msg);
            printf("MSG:%s\n",receBuffer);

            zmq_msg_init_size(&msg,strlen(receBuffer));
            memcpy((char*)zmq_msg_data(&msg),receBuffer,strlen(receBuffer
            zmq_msg_send(&msg,publiser,0);
            zmq_msg_close(&msg);
        }

    }
    zmq_close(publiser);
    zmq_close(receiver);
    zmq_ctx_destroy(context);
    return true;
}

 

3.客户端代码

#include 
 #include 
 #include 
 #include 
 #include 
 #include 
#include 
#define NAME_SIZE 64
#define BUFFER_SIZE 1024
 
struct worker_t
{
      worker_t()
      {
          context = NULL;
          endpoint = NULL;
      }
      void* context;
      char* endpoint;
  };
void* worker(void* argv)
{
    assert(argv);
    worker_t* worker = (worker_t*)argv;
    void* receiver = zmq_socket(worker->context,ZMQ_SUB);
    zmq_setsockopt(receiver,ZMQ_SUBSCRIBE,"",0);
    zmq_connect(receiver,worker->endpoint);
    zmq_pollitem_t items[] = 
    {   
        {receiver,0,ZMQ_POLLIN,0}
    };  
    while(true)
    {   
        char buffer[BUFFER_SIZE];
        memset(buffer,0,sizeof(buffer));
        int rc = zmq_poll(items,1,-1);
        if(rc==-1)
            break;
        if(items[0].revents & ZMQ_POLLIN)
        {   
            zmq_msg_t reply;
            zmq_msg_init(&reply);
            zmq_msg_recv(&reply,receiver,0);
                         int size = zmq_msg_size(&reply);
            size = (size > NAME_SIZE)? NAME_SIZE-2 : size;
            memcpy(buffer,(char*)zmq_msg_data(&reply),size);
            buffer[size+1] = 0;
            zmq_msg_close(&reply);
            printf("%s\n",buffer);
        }
    }
    zmq_close(receiver);
    return NULL;
}

int main(int argc,char** argv)
{
    if(argc < 4)
    {
        printf("syntax:%s \n",argv[0]);
        exit(EXIT_SUCCESS);
    }
    void* context = zmq_init(1);
    void* sender = zmq_socket(context,ZMQ_PUSH);
    zmq_connect(sender,argv[2]);

    worker_t arg;
    arg.context = context;
    arg.endpoint = argv[3];
    pthread_t work;
    pthread_create(&work,NULL,worker,&arg);
    while(true)
    {
        char buffer[BUFFER_SIZE];
        char content[BUFFER_SIZE];
        memset(buffer,0,sizeof(buffer));
        memset(content,0,sizeof(content));
        std::cin.getline(buffer,sizeof(buffer));
        if(!strcmp(buffer,"quit"))
            break;

        sprintf(content,"%s:%s",argv[1],buffer);
        zmq_msg_t msg;
        zmq_msg_init_size(&msg,strlen(content));
        memcpy((char*)zmq_msg_data(&msg),content,strlen(content));
        zmq_msg_send(&msg,sender,0);
        zmq_msg_close(&msg);
    }
    zmq_close(&sender);
    zmq_term(context);
    return 0;
}     


4. 总结

     这个实例通过ZeroMQ来实现的话,只需要短短的几十行代码即可完成,而如果采用传统的Socket编程的话,估计至少需要上百行的代码吧,再次被ZeroMQ所折服,这也是我想要学习ZeroMQ的原因,也希望那些想要从事服务器端开发的道友能够从ZeroMQ中找到惊喜,谢谢

你可能感兴趣的:(分布式消息队列)