Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Reopening" socket with the same identity failed #2010

Closed
tatraian opened this issue May 24, 2016 · 7 comments
Closed

"Reopening" socket with the same identity failed #2010

tatraian opened this issue May 24, 2016 · 7 comments

Comments

@tatraian
Copy link

@tatraian tatraian commented May 24, 2016

Hello,

I wrote the attached example code. Shortly: it uses only one thread, and has 3 sockets. Parent socket lives through the whole running. Once that it is created, we call the sendMessage function twice. It creates a socket and send a message to parent (and after close the socket).

If I set the identity I get only one message, but if I don't set identity I get both messages. Is this a bug or a design behavior of ZeroMQ?

#include <zmq.h>

#include <string>
#include <iostream>

void sendMessage(void* context, const std::string& parent)
{
    void* socket = zmq_socket(context, ZMQ_DEALER);
    zmq_setsockopt(socket, ZMQ_IDENTITY, "XXX", 4);
    zmq_connect(socket, parent.c_str());
    std::cerr << "Sending status: " << zmq_send(socket, "Akarmi", 6, 0) << std::endl;
    zmq_disconnect(socket, parent.c_str());
    zmq_close(socket);
}

int main()
{
    void* context = zmq_ctx_new();
    void* parent  = zmq_socket(context, ZMQ_ROUTER);
    zmq_bind(parent, "inproc://parent");

    sendMessage(context, "inproc://parent");
    sendMessage(context, "inproc://parent");

    char buffer[255];
    std::cerr << "Recv status: " << zmq_recv(parent, buffer, 255, ZMQ_DONTWAIT) << std::endl;
    std::cerr << buffer << std::endl;
    std::cerr << "Recv status: " << zmq_recv(parent, buffer, 255, ZMQ_DONTWAIT) << std::endl;
    std::cerr << buffer << std::endl;
    std::cerr << "Recv status: " << zmq_recv(parent, buffer, 255, ZMQ_DONTWAIT) << std::endl;
    std::cerr << buffer << std::endl;
    std::cerr << "Recv status: " << zmq_recv(parent, buffer, 255, ZMQ_DONTWAIT) << std::endl;
    std::cerr << buffer << std::endl;

    zmq_close(parent);
    zmq_ctx_destroy(context);
    return 0;
}
@tatraian
Copy link
Author

@tatraian tatraian commented May 24, 2016

If I set ZMQ_ROUTER_HANDOVER on parent socket then I get all messages, but my first messages identity is replaced to default. The second's identity remains "XXX".

@somdoron
Copy link
Member

@somdoron somdoron commented May 25, 2016

You cannot use the same identity for two different peers. So the behavior is following:

  • Without handover new peer will be rejected.
  • With handover, new peer will get the new identity and old peer will get random one.

Because you send the messages first and then read you get the first message with random identity.

In general try not to use identity, it is kind of obsolete concept.

@tatraian
Copy link
Author

@tatraian tatraian commented May 25, 2016

Thanks!

Than I close the issue.

@tatraian tatraian closed this May 25, 2016
@sunkin351
Copy link
Contributor

@sunkin351 sunkin351 commented May 26, 2016

If Identity is an obsolete concept, what is there to take its place? (And why don't you remove/replace it in the router socket either?)

@somdoron
Copy link
Member

@somdoron somdoron commented May 26, 2016

Setting the identity is obsolete, instead identification of peer should be part of the handshake at the application level. New server socket type doesn't have identity anymore, routing id which is integer.

I don't think we can remove it as alot of users are using it

@tatraian
Copy link
Author

@tatraian tatraian commented May 26, 2016

In this case if you have two backed router interfaces and one-to-one connection among client and services (I think this is typical in case of remote object calls) then you have to search connection about client and services twice: once in router socket (for low level socket selection by routing id) and once in the user created router code (replace routing id the the application level address).
Currently if you set the same identity in client to router and router to service channels then you don't have to modify the packet and search anything (except router socket, of course).
I just want mention that identity is very helpful in some situations.

@kmonson
Copy link

@kmonson kmonson commented Jun 6, 2016

Is there anyway to detect the case where there are duplicate identities on either side of the connection?

I've tried monitoring the connection and only see ACCEPTED for both connecting sockets. The only indication I have that there is a problem is missing expected log messages on the ROUTER side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.