zeromq / netmq

A 100% native C# implementation of ZeroMQ for .NET
Other
2.94k stars 742 forks source link

RequestSocket.Connect silently fails #1035

Open IsaacSherman opened 1 year ago

IsaacSherman commented 1 year ago

Environment

NetMQ Version:    4.0.1.10
Operating System:  Windows 10
.NET Version:     6.0

Expected behaviour

Start Server button becomes enabled every time the server dies. For this to happen, server count needs to go to zero. For that to happen, the kill signal needs to be sent, and for that to happen the connection on port 6001 needs to be made.

Actual behaviour

All of the expected behavior happens the first time through. On subsequent attempts, the connection to port 6001 silently fails.

Steps to reproduce the behaviour

Run the app from this repo Click Start Server Click Start Worker Wait for server to "crash" Set a breakpoint at ZmqHelloServer.cs line 46 Click Start Server Click Start Worker Wait for server to "crash" Step through code at line 46. I used netstat to verify that sock.Connect fails silently. The result is the message never makes it to the WatchThread. See this SO question for further details/background: https://stackoverflow.com/questions/73948752/netmq-response-socket-poll-fails-after-succeeding-one-time Relevant code is in MainWindowViewModel at line 54. The ReceiveReady function at line 77 is not used because I'm not polling any more. Either way, the important thing is the message never comes through.

IsaacSherman commented 1 year ago

Here's more minimal code to reproduce. Dump this into a new console app with the Nuget dependencies loaded.

using NetMQ;
using NetMQ.Sockets;

namespace ZmqMinDemo;

public class Program
{
    private const string connect = "tcp://127.0.0.1:9999";
    private static TimeSpan _delay = TimeSpan.FromMilliseconds(1000);
    public static void Main()
    {
        Thread t = new Thread(Listen);
        t.Start();
        Thread.Sleep(10);
        RequestSocket sock = new();
        sock.Connect(connect);
        sock.SendFrameEmpty();
        //Uncommenting the following line will cause the break in Listen to be hit
        //var msg = sock.ReceiveFrameString();
        sock.Disconnect(connect);
        sock.Close();
        sock = new();
        sock.Connect(connect);
        sock.SendFrame("die");
        sock.Disconnect(connect);
        sock.Close();
    }

    private static void Listen(object? obj)
    {
        ResponseSocket resp = new();
        resp.Bind(connect);
        while (true)
        {
            resp.TryReceiveFrameString(_delay, out string? msg);
            if(msg != null) 
                resp.SendFrameEmpty();
            if (msg == "die") 
                break; 
        }
    }
}