Consider the following:
- a set of 3 logical services:
S1
,S2
andS3
- two instances of each service are running, so we have the following processes:
S1P1
,S1P2
,S2P1
,S2P2
,S3P1
,S3P2
- a
ZeroMQ
broker running in a single process and reachable by all service processes
A logical service, let's say S1
, publishes a message M1
that is of interest to logical services S2
and S3
. Only one process of each logical service must receive M1
, so let's say S2P1
and S3P2
.
I have tried the following, but without success:
- broker thread 1 is running a
XSUB/XPUB
proxy - broker thread 2 is running a
ROUTER/DEALER
proxy with theROUTER
connected to theXPUB
socket and subscribed to everything (for logicalS1
) - broker thread 3 is running a
ROUTER/DEALER
proxy with theROUTER
connected to theXPUB
socket and subscribed to everything (for logicalS2
) - broker thread 4 is running a
ROUTER/DEALER
proxy with theROUTER
connected to the XPUB socket and subscribed to everything (for logicalS3
) - each logical service process is running a
REP
socket thread connected to the brokerDEALER
socket
I figured that the XSUB/XPUB
proxy would give me publish/subscribe semantics and that the ROUTER/DEALER
proxies would introduce a competition between the REP
sockets for the messages sent by the XSUB/XPUB
proxy.
How can I combine ZeroMQ
sockets to accomplish this?
Update1
I know "without success" isn't helpful, I've tried different configurations and got different errors. The latest configuration I tried is the following:
(XSUB proxy=> XPUB) => (SUB copyLoop=> REQ) => (ROUTER proxy=> DEALER) => REP
The copyLoop goes like this:
public void start() {
context = ZMQ.context(1);
subSocket = context.socket(ZMQ.SUB);
subSocket.connect(subSocketUrl);
subSocket.subscribe("".getBytes());
reqSocket = context.socket(ZMQ.REQ);
reqSocket.connect(reqSocketUrl);
while (!Thread.currentThread().isInterrupted()) {
final Message msg = receiveNextMessage();
resendMessage(msg);
}
}
private Message receiveNextMessage() {
final String header = subSocket.recvStr();
final String entity = subSocket.recvStr();
return new Message(header, entity);
}
private void resendMessage(Message msg) {
reqSocket.sendMore(msg.getKey());
reqSocket.send(msg.getData(), 0);
}
The exception I get is the following:
java.lang.IllegalStateException: Cannot send another request
at zmq.Req.xsend(Req.java:51) ~[jeromq-0.3.4.jar:na]
at zmq.SocketBase.send(SocketBase.java:613) ~[jeromq-0.3.4.jar:na]
at org.zeromq.ZMQ$Socket.send(ZMQ.java:1206) ~[jeromq-0.3.4.jar:na]
at org.zeromq.ZMQ$Socket.sendMore(ZMQ.java:1189) ~[jeromq-0.3.4.jar:na]
at com.xyz.messaging.zeromq.SubReqProxyConnector.resendMessage(SubReqProxyConnector.java:47) ~[classes/:na]
at com.xyz.messaging.zeromq.SubReqProxyConnector.start(SubReqProxyConnector.java:35) ~[classes/:na]
I'm running JeroMQ 0.3.4, Oracle Java 8 JVM and Windows 7.