netmq icon indicating copy to clipboard operation
netmq copied to clipboard

StreamSocket does not send empty connect/disconnect message when peers connect/disconnect

Open jens-auer opened this issue 1 year ago • 2 comments

Environment

NetMQ Version:    4.0.1.13
Operating System: Windows 10
.NET Version: 8

Expected behaviour

In ZeroMQ, stream sockets send an empty message for peer connect / disconnect:

When a connection is made, a zero-length message will be received by the application. Similarly, when the peer disconnects (or the connection is lost), a zero-length message will be received by the application.

This seems not to be the case for NetMQ. The following code blocks on the first s1.ReceiveMultipartBytes()

[TestClass]
public class TestStreamSocket
{
    [TestMethod]
    public void TestConnectDisconnectMessages()
    {
        var s1 = new StreamSocket();
        var port = s1.BindRandomPort("tcp://127.0.0.1");

        var s2 = new StreamSocket();
        s2.Connect($"tcp://127.0.0.1:{port}");

        var connectMsg = s1.ReceiveMultipartBytes();
        Assert.AreEqual(2, connectMsg.Count);
        Assert.AreNotEqual(0, connectMsg[0].Length);
        Assert.AreEqual(0, connectMsg[1].Length);

        s2.Disconnect($"tcp://127.0.0.1:{port}");
        var disconnectMsg = s1.ReceiveMultipartBytes();
        Assert.AreEqual(2, connectMsg.Count);
        Assert.AreNotEqual(0, connectMsg[0].Length);
        Assert.AreEqual(0, connectMsg[1].Length);
    }
}

ZeroMQ has a socket option ZMQ_STREAM_NOTIFY to enable (=1) or disable this behavior. Default is enabled (=1).

As an example, the following Python code uses libzmq and shows the expected behavior:

import zmq

ctx = zmq.Context()

s1 = ctx.socket(zmq.STREAM)
s2 = ctx.socket(zmq.STREAM)

port = s1.bind_to_random_port("tcp://127.0.0.1")

s2.connect(f"tcp://127.0.0.1:{port}")
connect = s1.recv_multipart()
print(connect)

s2.disconnect(f"tcp://127.0.0.1:{port}")
s2.close()

disconnect = s1.recv_multipart()
print(disconnect)

Output:

[b'\x00\x80\x00\x00)', b'']
[b'\x00\x80\x00\x00)', b'']

Actual behaviour

  • No message received when s2 connects to s1.
  • No message received when s2 disconnects.

Steps to reproduce the behaviour

Run above unit test.

jens-auer avatar Jun 18 '24 09:06 jens-auer

Would you be able to make a pull request?

drewnoakes avatar Jun 19 '24 00:06 drewnoakes

I can take a look. Is it possible to use a Monitor to detect a connect / disconnect and get the corresponding identity via socket options?

jens-auer avatar Jun 19 '24 05:06 jens-auer