Каков правильный способ ожидания соединений?

Я пытаюсь реализовать простую передачу сообщений между двумя приложениями с помощью NetMQ (чуть более подробное описание того, чего я пытаюсь достичь, приведено ниже).
После нескольких проб и ошибок я обнаружил, что не могу просто отправляйте или получайте сообщения сразу после вызовов Connect/Bind, поскольку они не блокируют и фактически возвращаются, даже если соединение еще не установлено.
На данный момент я решил эту проблему с помощью Thread.Sleep(), но это имеет неприятный вкус и определенно не годится для производственной системы.

Итак, вопрос в том, как это сделать в NetMQ/ZeroMQ?

Пример клиента:

        using (NetMQContext ctx = NetMQContext.Create())
        {
            using (var client = ctx.CreatePushSocket())
            {
                client.Connect("tcp://127.0.0.1:5555");
                Thread.Sleep(100); // wait for connection

                for (int i = 0; i < 5; i++) 
                {
                    client.Send("test " + i , true);
                }
            }
        }
    }

Пример сервера:

    using (NetMQContext ctx = NetMQContext.Create())
    {
        using (var server = ctx.CreatePullSocket())
        {
            server.Bind("tcp://127.0.0.1:5555");
            Thread.Sleep(100); // wait for connection
            while (true)
            {
                var str = server.ReceiveString();
                Console.Out.WriteLine(str);
                Thread.Sleep(60*1000); // do msg processing
            }
        }
    }

Описание того, чего я пытаюсь достичь:

Клиент — отправляет сообщения на один сервер. Клиент не должен блокировать и не должен отбрасывать сообщения, когда сервер недоступен. Клиент может выйти в оффлайн/онлайн в любое время.

Сервер — получает сообщения от одного клиента. Сервер блокируется до получения сообщения. Сервер должен выполнять длительную обработку сообщения и не должен терять никакие другие сообщения во время обработки. Сервер может перейти в оффлайн/онлайн в любое время.


person orom    schedule 28.03.2014    source источник
comment
Пример на сайте netmq не передает true в Send.   -  person Peter Ritchie    schedule 22.06.2014


Ответы (2)


Лучшее решение для вашего сна на стороне сервера — создать средство опроса сокетов и опрашивать опрашивающий сокет до тех пор, пока не будет получено сообщение. Это позволяет избежать бесполезного сна и в целом делает код более компактным.

На стороне клиента лучшим решением, вероятно, будет создание двух сокетов (один для отправки сообщений, один для получения) и заставить сервер объявить о своем присутствии, чтобы клиент мог отправить сообщение. Поскольку ZeroMQ эффективно обрабатывает несколько подключений, это решение будет работать очень хорошо.

person blockchaindev    schedule 29.03.2014

как получение, так и отправка могут ждать до тех пор, пока не будут выполнены, вы передали true параметру dontWait в своем примере, просто удалите его, и он отправит сообщение, когда сможет.

Для приема вам не нужно спать, потому что он будет ждать, пока сообщение не будет доступно.

Как было предложено, использование Poller также является решением (вы можете опрашивать, когда сокет может отправлять и когда сообщения готовы к использованию), взгляните на тестирование класса poller: https://github.com/zeromq/netmq/blob/3.3.3-rc5/src/NetMQ.Tests/PollerTests.cs.

person somdoron    schedule 22.06.2014