Basic Dealer-Router Socket not working - ruby

I'm trying to implement the basic DEALER - ROUTER socket in ZeroMQ.
My Question has multiple parts.
Before that, here are my sample scripts
DEALER SCRIPT
ROUTER SCRIPT
QUESTION -
Firstly,The vanilla DEALER SCRIPT of mine is unable to read the message from the SOCKET.
Secondly, When I'm implementing a DEALER or ROUTER PATTERN, is it mandatory to pass the IDENTITY across(as a part of header) i.e can't the message be sent without any IDENTITY.
In other words can a DEALER - ROUTER pattern (can be see below) can co-exists and pass message among themselves without sending identity info in header.
DEALER WITHOUT ANY IDENTITY
ROUTER WITHOUT ANY IDENTITY
because, I'm unable to get it working without the identity as well.
NOTE : - The Zeromq ruby library(ruby client) currently in picture is ffi-rzmq

Your code shows a lot of misunderstandings about how ZMQ works, I suggest you read the guide and follow the Ruby examples to set up your scripts.
Here's the problems that I see:
In your DEALER script, you explicitly receive the identity - it will never get its own identity as part of the message, this is silently removed by ZMQ because it's not intended to be message data, it's intended to be an "address" used by the ROUTER socket. So, you're actually receiving the delimiter into your identity variable, the message into your delimiter variable, and then nothing is left and your msg variable is empty. If you puts the values of all three variables, you'll see it.
You don't need a ZMQ poller in your DEALER socket. Pollers are intended to receive messages from multiple sockets, you're only using one socket. I don't know whether it's actually intended to work with one socket at all, but at any rate it's needless additional complexity, rip it out. See here for a simple send/receive example from the guide (if you just change the socket type to DEALER, add your "particulars" - identity, address, port, etc - and omit the send, it should work for you)
In your second example, where you don't set an identity, the ROUTER socket doesn't address the message to any connected client - you always need to send the client identity as the first frame of the message. Typically, you'll receive a message from your client, which includes its identity, and you'll use that identity to send the message back. You're only able to skip that in the first example because your script already knows the identity, "client"

Related

ZMQ: Multiple request/reply-pairs

ZeroMQs Pub/Sub pattern makes it easy for the server to reply to the right client. However, it is less obvious how to handle communication that cannot be resolved within two steps, i.e. protocols where multiple request/reply pairs are necessary.
For example, consider a case where the client is a worker which asks the server for new work of a specific type, the server replies with the parameters of the work, the client then sends the results and the server checks these and replies whether they were correct.
Obviously, I can't just use recv,send,recv,send sequentially and assume that the first and the second recv are from the same client. What would be the idiomatic way to use multiple recv,send pairs without having to handle messages from other clients inbetween?
Multiple Request/Reply pairs can be made through the use of ZMQ_ROUTER sockets. I recommend using ZMQ_REQ sockets on the clients for bidirectional communication.
If you want to have multiple clients accessing a single server you could use a router socket on the server and request sockets on the clients.
Check out the ZMQ guide's section on this pattern:
http://zguide.zeromq.org/php:chapter3#The-Asynchronous-Client-Server-Pattern
All the clients will interact with the server in the same pattern as Pub/Subs except they will all point at a single server Router socket.
The server on the other hand will receive three messages for every single message a client sends. These parts represent:
Part0 = Identity of connection (random number of which client it is)
Part1 = Empty frame
Part2 = Data of the ZMQ message.
Reference:
http://zguide.zeromq.org/php:chapter3#ROUTER-Broker-and-REQ-Workers
The identity can be used to differentiate between clients accessing on a single port. Repacking the message in the same order and responding on the router socket (with a different data frame) will automatically route it to the client who sent the message.

How to reconnect the Dealer in Zeromq

I'm using the pattern: Router-Dealer
Router send messages to Dealer(A) all the time.
Dealer just receive message (SOCKOPT_IDENTITY: A).
Work fine in this time.
Then
i press Ctrl-C to stop the Dealer , and reconnect.
Now i got nothing ~~
Is there anything wrong?
How can i fix it?
Thanks.
You are using the wrong kind of sockets and/or direction of messages.
I would be easier to understand what you would like to do if you write what you are using the socket for.
Assuming that you want to use Dealer and Router sockets then you should send the message in the other direction (Dealer => Router).
The Router socket connects many inputs to a single output or a single input to many outputs. This is done by adding/removing an identifier to the message, that describes where it came from or where it should go.
So in your case when you are trying to send a message from the router, the router socket will try to remove the identifier from the message, so that it can understand which connection it should forward the message on. So if you really want this then you need to associate your dealer connection with an identifier and then add that to the message that your sending through the router.
But I'm pretty sure that you actually want to use another combination of zmq sockets.

How to fetch 0mq socket structure from fd?

We have an application in which we are listening on a socket. When clients connect, we need to know the per client “fd” and the peer address. This info can be fetched using the socket monitors. Subsequently, we need to send data separately for each client. (not send same data to all clients). Is there a standard API to get socket structure from “fd” which we can use in send API?
My understanding is that fd is only used as a field of the zmq_pollitem_t struct used in zmq_poll or other pollers. There it is used for when you want to interface ZMQ sockets with other non-ZMQ pollers (so if you're using zmq_poll it shouldn't be set to anything other than 0). So, in the case you are using a non-ZMQ poller, you're setting the fd value, not getting it.
Is this the use of fd you're referring to? If not, could you update your question to be more specific?

How do I get a Faye client given a client ID?

Faye allows you to monitor various events, such as handshake or subscribe. These callback blocks are only supplied the client_id value rather than the client itself. For example:
server = Faye::RackAdapter.new(mount: '/faye', timeout: 45)
server.bind(:handshake) do |client_id|
puts "Received handshake from #{client_id}"
end
How can I access the client given the client_id? Or how can I access more information in the handshake, such as cookies provided in the request header (if that info is even available)?
I think my original question is based upon a lack of understanding on how Faye works in two regards. Instead of deleting my question, I'm going to answer it for anyone else who comes across this with a similar question. (If my answer is wrong in any way, please comment or edit!)
First, at no point is access to the connected client available due to the way Faye is implemented with regards to the Bayeux protocol. All communications are carried out via channel broadcasting, meaning all connections listening to a channel will receive the message being sent.
Second, the code I pasted in the question deals with monitoring. What I'm really looking for is an extension.
In order to achieve authentication given my original question, I need to pass whatever authentication value is needed (whether it's a cookie value, auth token, etc.) as part of the message['ext'] value (per the example on the extensions page). Then, on the server side, I need to listen for messages on the /meta/handshake channel, setting message['error'] to some value in the case of value.

Can anyone explain the request-reply broker zeromq example?

I'm refering to the 'A Request-Reply Broker' in the Zeromq documentation: http://zguide.zeromq.org/chapter:all
I'm getting the general gist of the app: it acts like an intermediary and routes messages from the client to the server and back again.
What I'm not getting though is how it makes sure the correct response from a server is sent to the correct client which originally made the request. I don't see anything in the code example which makes sure about this.
Now in the example they only send 1 message (hello) and 1 response (world), so even if messages are mixed up it doesn't matter, but I'm guessing that the testclient and server are kept deliberately simple.
Any thoughts are welcome...
All zeromq sockets implicitly have an identity associated with them. (You can obtain this identity with zmq_getsockopt().)
For bi-directional socket types not XREQ or XREP, this identity is automatically transferred as part of every message sent over the socket. The REP socket uses this identity to route the response message back to the appropriate socket. This has the effect of automatic routing.
Under the hood, identities are transferred via multipart messages. The first message in a multipart message will contain the socket identity. An empty message will follow, followed by all messages specified by the user. The REQ and REP sockets deal with these prefixed messages automatically. However, if you are using XREQ or XREP sockets, you need to populate these identity messages yourself.
If you search for "identity" on the ZMQ Guide, you should find all the details you will ever want to know about how identities and socket routing works.
Ok in chapter 3 they all of a sudden explain that there is an underlying concept of an 'envelope' which the req/resp pattern invisubly uses.
This explains how it works.

Resources