我正在尝试使用libzmq C API在C模型中获取异步客户端/服务器。
我在Linux平台上使用ZeroMQ 3.2.2,我试图开始工作的模式如下所示:
>Client -> DEALER
>
>Router -> ROUTER
>--- proxy ---
>Dealer -> DEALER
>
>Workers-> DEALER
我需要客户端无阻塞,但仍需要接收对消息的响应。从我看到的例子中,我的理解是使用带有zmq_proxy的ROUTER-DEALER应该将消息返回给初始客户端。
但是,通过将捕获套接字附加到zmq_proxy,似乎不会路由响应。
当我将客户端更改为REQ而工作者更改为REP时,所有工作都按预期工作。 任何对我出错或误解的反馈都会受到欢迎。
3个组件(客户,经纪人和工人)在下面。
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
int main (void)
{
printf ("Connecting to hello world broker...\n");
void *ctx = zmq_ctx_new ();
void *requester = zmq_socket (ctx, ZMQ_DEALER);
//void *requester = zmq_socket (ctx, ZMQ_REQ);
zmq_connect (requester, "tcp://10.1.1.31:5555");
printf ("Sending Request : HELLO \n");
int rc = zmq_send (requester, "HELLO", 6, 0);
if (rc > 0) {
printf ("Success : Sent size ... %d!\n",rc);
} else {
printf("Error: %s\n", zmq_strerror(errno));
}
printf ("Wait for response ..\n");
char buffer [256];
zmq_recv (requester, buffer, 256, 0);
printf ("Response Received : %s\n",&buffer);
zmq_close (requester);
zmq_ctx_destroy (ctx);
return 0;
}
#define _MULTI_THREADED
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <zmq.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
#define ZFRAME_MORE 1
#define ZFRAME_REUSE 2
#define ZFRAME_DONTWAIT 4
static void *proxy_capture (void *ctx)
{
int zerr = 0 ;
int rRes;
void *worker = zmq_socket (ctx, ZMQ_DEALER);
zerr = zmq_connect (worker, "ipc://capture.ipc");
if (zerr != 0)
{
printf ("\n-------------- > proxy_capture bind error : %s\n", zmq_strerror(errno));
return 0;
}
while (1) {
char buf [256];
int rc = zmq_recv (worker, buf, 256, 0);
assert (rc != -1);
printf ("Capture value : %s !\n", &buf);
}
}
int main(int argc, char *argv[])
{
int zerr = 0 ;
int rc = 0 ;
int rRes;
// Frontend socket talks to clients over TCP Port
void *ctx = zmq_ctx_new ();
void *frontend = zmq_socket (ctx, ZMQ_ROUTER);
zerr = zmq_bind (frontend, "tcp://10.1.1.31:5555");
if (zerr != 0)
{
printf ("\nFrontend bind error : %s\n", zmq_strerror(errno));
return 0;
}
// Backend socket talks to workers
void *backend = zmq_socket (ctx, ZMQ_DEALER);
zerr = zmq_bind (backend, "tcp://10.1.1.31:6555");
if (zerr != 0)
{
printf ("\nBackend bind error : %s\n", zmq_strerror(errno));
return 0;
}
void *capture = zmq_socket (ctx, ZMQ_DEALER);
zerr = zmq_bind (capture, "ipc://capture.ipc");
if (zerr != 0)
{
printf ("\nCapture bind error : %s\n", zmq_strerror(errno));
return 0;
}
pthread_t capworker;
rc = pthread_create(&capworker, NULL, proxy_capture, ctx);
zmq_proxy (frontend, backend, capture);
while (1) {
printf ("Broker loop …\n");
sleep(1);
}
sleep(1);
zmq_ctx_destroy (&ctx);
printf ("\nEnd server…\n");
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <zmq.h>
#include <unistd.h>
#include <assert.h>
#define ZFRAME_MORE 1
#define ZFRAME_REUSE 2
#define ZFRAME_DONTWAIT 4
int main(int argc, char *argv[])
{
int zerr = 0 ;
int rc = 0 ;
int rRes;
void *ctx = zmq_ctx_new ();
//void *worker = zmq_socket (ctx, ZMQ_DEALER);
void *worker = zmq_socket (ctx, ZMQ_REP);
zerr = zmq_connect (worker, "tcp://10.1.1.31:6555");
sleep(1);
if (zerr != 0)
{
printf ("Worker connect error : %s\n", zmq_strerror(errno));
return 0;
}
while (1) {
char buf [256];
rc = zmq_recv (worker, buf, 256, 0);
assert (rc != -1);
printf ("Received : %s !\n", &buf);
printf ("Responding to Client... !\n");
rc = zmq_send(worker, "WORLD", 6, 0);
if (rc > 0) {
printf ("Success : Sent size ... %d!\n",rc);
//break;
} else {
printf("Error: %s\n", zmq_strerror(errno));
}
}
zmq_close (worker);
zmq_ctx_destroy (ctx);
return 0;
}
TestClient的
连接到hello world broker ...
发送请求:你好 成功:发送尺寸... 6!
等待回复..TestBroker
捕捉价值:!
夺取价值:你好! &lt; - 来自客户捕获的请求
价值:世界! &lt; - 来自工人的回复 捕获价值:世界!TestWorker
收到:!
回应客户......!
成功:发送尺寸... 6!
收到了:你好! 回应客户......!
成功:发送尺寸...
6!
所以看来工作人员会响应,但路由器的响应丢失或错误地指向客户端?
请求任何帮助
答案 0 :(得分:0)
我偶然发现了我对捕捉部分zmq_proxy问题的回答,我试图理解。
对于您的问题,您希望客户端是异步的,而不是使用REQ,您使用了DEALER。
以下是我如何使其异步。我的zeromq版本是4.2.1。
// Socket to talk to server
void *context = zmq_ctx_new();
void *requester = zmq_socket (context, ZMQ_REQ);
int timeout = 5000; //Timeout of 5 seconds to make sure not having it hang either while sending or receving...
int linger = 0;
zmq_setsockopt (requester, ZMQ_LINGER, &linger, sizeof(int));
zmq_setsockopt (requester, ZMQ_SNDTIMEO, &timeout, sizeof(int));
zmq_setsockopt (requester, ZMQ_RCVTIMEO, &timeout, sizeof(int));
int connection_status = zmq_connect (requester, "tcp://localhost:5559");
您可以通过将其设置为0来使用“逗留”,也可以在从REQ发送到代理时使用标志ZMQ_DONTWAIT