关于ipc://和并发的ZeroMQ REQ / REP

时间:2012-06-06 16:29:00

标签: linux unix rpc zeromq json-rpc

我使用REQ / REP 0MQ ipc:// socket实现了一个JSON-RPC服务器,我遇到了奇怪的行为,我怀疑这是因为ipc://底层unix socket不是真正的socket ,而是一根烟斗。

从文档中,必须强制执行严格的zmq_send()/ zmq_recv()更改,否则无序zmq_send()将返回错误。

但是,我希望强制执行是每个客户端,而不是每个套接字。当然,对于Unix套接字,只有一个从多个客户端到服务器的管道,因此服务器将不知道它与谁通话。两个客户端可以同时使用zmq_send(),服务器会将此视为违规交替。

序列可能是:

  • ClientA:zmq_send()
  • ClientB:zmq_send():它会阻塞直到 其他发送/接收完成?它会返回-1吗? (我怀疑它会 使用ipc://由于固有的低级问题,但使用TCP可以 区分两个客户)
  • ClientA:zmq_recv()
  • ClientB:zmq_recv()

那么tcp://套接字呢?它会同时工作吗?我应该使用其他一些锁定机制来解决这个问题吗?

示例服务器:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include <czmq.h>


int main(void) 
{
    zctx_t *zctx   ;
    void *zsocket_rpc;

        printf ("rpcserver create context\n");
    zctx = zctx_new();
        printf ("rpcserver create socket\n");
    zsocket_rpc = zsocket_new (zctx, ZMQ_REP);
        if (!zsocket_rpc) {
                fprintf (stderr, "zsocket_rpc is NULL\n");

                exit(1);
        }
    zsocket_bind (zsocket_rpc, "ipc:///tmp/rpcserver");

        for(;;) {
                int rc;

                char *msg = zstr_recv(zsocket_rpc);
                printf ("rpcserver received %s\n", msg);

                printf ("rpcserver sleep\n");
                usleep(200000);

                printf ("rpcserver send %s\n", msg);
                rc = zstr_send(zsocket_rpc, msg);
                if (rc < 0) {
                        fprintf (stderr, "rpcserver zstr_send returned %d\n", rc);
                        continue;
                }
                free(msg);
        }

}

示例客户端(以./rpcclient字母发布):

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <czmq.h>

int main(int argc, char *argv[]) 
{
        char msg[] = "A:MESSAGE 999";
    zctx_t *zctx;
    void *zsocket_rpc;

        if (argc != 2) {
                fprintf (stderr, "Usage: rpcclient letter\n");
                exit(1);
        }

    zctx = zctx_new();
        printf ("rpcclient new socket\n");
    zsocket_rpc = zsocket_new (zctx, ZMQ_REQ);
        if (!zsocket_rpc) {
                fprintf (stderr, "zsocket_rpc is NULL\n");

                exit(1);
        }
        printf ("rpcclient connect\n");
    zsocket_connect (zsocket_rpc, "ipc:///tmp/rpcserver");

        for (int cnt = 0; cnt < 1000; cnt++) {
                int rc;

                sprintf (msg, "%c:MESSAGE %03d", argv[1][0], cnt);
                printf  ("rpcclient send %s\n", msg);
                rc = zstr_send(zsocket_rpc, msg);
                if (rc < 0) {
                        fprintf (stderr, "rpcclient zstr_send returned %d\n", rc);
                        continue;
                }
                printf ("rpcclient sleep...\n");
                usleep(200000);

                char *reply = zstr_recv(zsocket_rpc);
                printf  ("rpcclient recv %s\n", reply);

                free(reply);
        }

}

2 个答案:

答案 0 :(得分:1)

您必须解释哪些事件序列无法执行您想要的操作。这样你的问题就不明显了。

答案 1 :(得分:0)

谢谢Pieter。我道歉,我今天做的大量测试证实,即使有多个客户也在ipc上,REQ / REPLY仍然坚如磐石:// 我认为这个问题已经结束了。

(问题是由于多个线程调用RPC函数而没有锁定......像往常一样)