У меня есть класс сервера публикации сообщений, который создает сокет PUB при создании со следующим кодом:

this.context = NetMQContext.Create();
this.pubSocket = this.context.CreatePublisherSocket();
var portNumber = this.installerSettings.PublisherPort;
this.pubSocket.Bind("tcp://127.0.0.1:" + portNumber);

При отправке сообщения с помощью messagePublishingServer.Publish(message) выполняется:

this.pubSocket.SendMoreFrame(string.Empty).SendFrame(message);

Следующий тест xBehave ...

    [Scenario]
    public void PublishMessageScenario()
    {
        MessagePublishingServer messagePublishingServer = null;
        NetMQContext context;
        NetMQ.Sockets.SubscriberSocket subSocket = null;
        string receivedMessage = null;

        "Given a running message publishing server"._(() =>
        {
            var installerSettingsManager = A.Fake<IInstallerSettingsManager>();
            var settings = new InstallerSettings { PublisherPort = "5348" };
            A.CallTo(() => installerSettingsManager.Settings).Returns(settings);
            messagePublishingServer = new MessagePublishingServer(installerSettingsManager);
        });

        "And a subscriber connected to the publishing server"._(() =>
        {
            context = NetMQContext.Create();
            subSocket = context.CreateSubscriberSocket();
            subSocket.Options.ReceiveHighWatermark = 1000;
            subSocket.Connect("tcp://127.0.0.1:5348");
            subSocket.Subscribe(string.Empty);
        });

        "When publishing a message"._(() =>
        {
            messagePublishingServer.Publish("test message");

            // Receive the topic
            subSocket.ReceiveFrameString();

            // and the message
            receivedMessage = subSocket.ReceiveFrameString();
        });

        "Then the subscriber must have received it"._(() =>
        {
            receivedMessage.Should().NotBeNullOrEmpty();
            receivedMessage.Should().Be("test message");
        });
    }

... блоки в первом subSocket.ReceiveFrameString(), которые я считаю неожиданными. Разве сокет подписчика не должен был поставить опубликованное сообщение в очередь до тех пор, пока не будет вызвано получение?

0
Andrey 26 Окт 2015 в 21:09

2 ответа

Лучший ответ

Издатель похож на радио: если вы не были подключены и не подписывались, когда издатель опубликовал, вы пропустите сообщение. Мой совет - после подключения абонента перевести в спящий режим 100 мс (только для тестирования).

1
somdoron 26 Окт 2015 в 23:31

Из источника (ReceivingSocketExtensions.cs):

    /// Receive a single frame from socket, blocking until one arrives, and decode as a string using ...
    public static string ReceiveFrameString([NotNull] this IReceivingSocket socket)

А также

    /// If no message is immediately available, return <c>false</c>.
    public static bool TryReceiveFrameString([NotNull] this IReceivingSocket socket, out string frameString)
0
Chaz 26 Окт 2015 в 18:26