我使用简单的请求/响应(客户端/服务器)模式已经很长时间了,它非常稳定。但是,我试图对此进行改进,以使如果另一个出现问题,则客户端和服务器都不会挂起。
原始(阻止)模式如下:
server.php
$zmq = new ZMQContext;
$sock = new ZMQSocket( $zmq, ZMQ::SOCKET_REP );
$sock->bind('tcp://*:5555');
while( true ){
echo "Server waiting..\n";
$ping = $sock->recv();
echo "Acknowledging ",$ping,"..\n";
$sock->send('Pong');
}
client.php
$zmq = new ZMQContext;
$sock = new ZMQSocket( $zmq, ZMQ::SOCKET_REQ );
$sock->connect('tcp://localhost:5555');
echo "Pinging..\n";
$sock->send('Ping');
echo "Client waiting..\n";
$pong = $sock->recv();
echo $pong," in reply. exiting.\n";
这非常好用,除非服务器在接收请求和发送响应之间死亡,否则客户端将永远挂起。
我想做的是不阻塞地执行$sock->recv
调用,如果没有响应,则允许超时。我试图通过轮询来实现这一目标。例如在客户端用类似下面的内容替换上面的阻塞recv调用:
client.php(轮询)
$zmq = new ZMQContext;
$sock = new ZMQSocket( $zmq, ZMQ::SOCKET_REQ );
$sock->connect('tcp://localhost:5555');
echo "Pinging..\n";
$sock->send('Ping');
echo "Client polling..\n";
$poller = new ZMQPoll;
$poller->add( $sock, ZMQ::POLL_IN );
$readable = [];
$writeable = [];
$poller->poll( $readable, $writeable, 1000 );
foreach( $readable as $sock ){
$pong = $sock->recv();
echo $pong," in reply. exiting.\n";
exit(0);
}
echo "No reply after 1s\n";
但是,我认为这种方法带来的风险是,如果两个或多个客户端大致同时发送了请求,则收到的回复可能是针对另一个客户端的。我假定同步方法保证不会发生这种情况,但是轮询方法会打破这种情况吗?
所以,我的问题简短。 请求套接字应该如何在不阻塞的情况下收到答复,同时确保消息不会发送给其他客户端?
Q:请求套接字如何在不阻塞的情况下接收答复,同时保证该消息不打算发送给另一个客户端?
欢迎使用零之禅(包括零保修)
除了如何规避互锁的策略外,REQ/REP
dFSA肯定会落入(人们只是不知道它会在多久之前出现,但会这样),我总是更喜欢双重侧无阻塞.poll()
-之前-.recv()
循环扫描,保证-“ 交付”和-“ 路由”是另一个层面的问题。
REQ/REP
(在ZMTP / RFC(28)中记录)本身就这样工作:
发送的每个请求都在所有服务中轮循,并且收到的每个答复都与最后发出的请求匹配。如果没有可用的服务,则套接字上的任何发送操作都应阻塞,直到至少有一项服务可用为止。 REQ套接字不得丢弃消息。
在REQ.send()
侧观察到,和
接收到的每个请求均在所有客户端中排队,并且发送的每个回复都路由到发出最后一个请求的客户端。如果原始请求者不再存在,则答复将被静默丢弃。
正在REP.recv()
侧观察。
最后一句解决了在REQ
被调用之前REP.send()
端不复存在的情况下的盗用交付。
另一方面,可能包含适当的自我验证传递(可以在做出{process | forget}决定之前验证'em),可能包含加密保证的“省钱”形式,以防有效载荷落入不正确的人手中(如果还没有“ proper” -Key的话,则为零值)-因此可能会在没有罪的情况下进行任意发送违反任何内容保护政策(但仍然是一种相当野蛮且在资源上昂贵的“昂贵”策略,不是吗?)所有,确实,所有情况都取决于您的偏好和健壮性水平,因为已设定了与安全相关的(主要是合理的合理水平)偏执狂,并且在所有领域问题的相关参与者和风险所有者之间相互认可了合理性。
查看您所有的问题域要求和风险,评估合理的问题缓解成本,并决定针对定制的多代理分布式应用程序级协议进行合理但经济高效的设计,这将添加ZeroMQ具有的所有要求已知省略了合并到智能,可伸缩,几乎零延迟的琐碎原型中(由于您的任何高级附加要求都会引入更多的工作要做/在此之前/期间,这些原型可能不适合作为原用例) /由于要传递邮件而后)