NetMQ в Publisher и абонат не работят

Опитвам се да внедря NetMQ Pub/Sub модела, но абонатът не получава никакви съобщения. Какво вероятно не е наред тук?

  private static void ServerTask()
    {
        using (var context = NetMQContext.Create())
        {
            using (var socket = context.CreateSubscriberSocket())
            {
                socket.Bind("tcp://10.120.19.109:5000");
                socket.Subscribe(string.Empty);

                while (true)
                {
                    Thread.Sleep(100);
                    string receivedMessage = socket.ReceiveString();
                    Console.WriteLine("Received: " + receivedMessage);
                }
            }
        }
    }

     public static void ClientTask()
    {
        using (NetMQContext ctx = NetMQContext.Create())
        {
            using (var socket = ctx.CreatePublisherSocket())
            {
                socket.Connect("tcp://10.120.19.109:5000");

                string obj = "hi";
                socket.Send(obj);
            }
        }
    }

И двете са в различни приложения.


person user2449952    schedule 13.08.2014    source източник


Отговори (2)


Ако сте нов в NetMQ, предлагам да прочетете ръководството за zeromq http://zguide.zeromq.org/page:all.

В крайна сметка вие изпращате съобщението, преди абонатът да изпрати абонамента.

Pubsub в zeromq и NetMQ е като радио, ще получавате съобщения само от момента, в който започнете да слушате.

Най-простият начин да го направите (не е решение в реалния живот) е да спите известно време след свързването.

За решение в реалния живот трябва да разбера какво се опитвате да постигнете

person somdoron    schedule 13.08.2014
comment
Изпълнявам serverTask() като конзолно приложение. Тъй като абонаментът е празен, предполагам, че ще слуша цялата тема за абонамент. След като е направено. Правя заявка към някакъв API, който вътрешно извиква ClientTask(). Според моето мислене, тъй като сървърът е в while(true), той ще продължи да търси споменатия адрес и трябва да се покаже веднага след публикуването на някое съобщение. - person user2449952; 13.08.2014
comment
Може да смятате издателя за сървър, а клиента за абонат. Във всеки случай, както казах преди, Pubsub в NetMQ е като радиото, ако имате нужда от нещо друго, може да изберете по-мъртви и рутерни модели. Прочетете ръководството, то вероятно ще отговори на всички ваши въпроси и много повече. - person somdoron; 14.08.2014
comment
Вие не отговаряте според описания сценарий. Съжалявам, но вашето общо изречение не е от полза. До момента ZeroMQ поддържа noth N -publisher 1 sub, както и 1Publisher и nSubscriber. Ако знаете, моля, кажете ми какво не е наред в текущата реализация. Ако искате повече информация, ще се радвам да споделя. - person user2449952; 14.08.2014
comment
Отговорът на вашия сценарий: вие изпращате съобщение до издателя, преди абонатът да изпрати абонамента до сървъра. За да избегнете това, поставете спящ режим от 100 ms, след като издателят се свърже. в netmq издателят филтрира съобщенията според абонаментите, след като издателят се свърже, абонатът изпраща абонамента на издателя. във вашия сценарий обаче вие ​​изпращате съобщението, преди издателят да получи клиентския абонамент. - person somdoron; 14.08.2014
comment
Благодаря. Това помогна. Но според вашите предложения не мога да разменям издателя и абоната. Трябва да изпратя данни от клиентска задача, която всъщност използвам за регистриране. ServerTask трябва да получи тези данни, които не могат да бъдат направени от издателя. Кой модел ZeroMQ би предложил в този сценарий. - person user2449952; 16.08.2014
comment
Това е перфектен модел за натискане и издърпване. Използвайте тип сокет за натискане за клиента и тип сокет за изтегляне за сървъра. с това решение няма да имате нужда от сън. - person somdoron; 16.08.2014
comment
Благодаря братле. Но имам проблем. Push socket Send() чака Pull Socket да получи, така че не се движи напред. - person user2449952; 18.08.2014
comment
push socket ще блокира при изпращане, ако не сте свързани към никакви сървъри. Можете да изпращате с dontSend, зададен на true и ще получите AgainException веднага, ако съобщението не може да бъде изпратено. сигурни ли сте, че се свързвате, преди да опитате да изпратите съобщение? можете ли да качите кода за натискане и издърпване? - person somdoron; 18.08.2014
comment
да схванах го. Ако и Дърпане, и Бутане са нагоре. Работи гладко. Притеснението ми беше само преразглеждането на този случай. Ако pull е надолу и Only Push е нагоре, в този случай трябва да обработим изключението или чрез dontWait, или чрез настройка SendTimeOut. нали - person user2449952; 19.08.2014
comment
Докато задавате DontWait =false в pushSocket. Не работи . някаква идея ? Въпреки че го накарах да работи, като зададох sendTimeout. - person user2449952; 19.08.2014
comment
трябва да зададете dontWait на true - person somdoron; 19.08.2014
comment
Извинете за забавения отговор. Всъщност имах предвид същото.. Задавам DontWait на true. Гнездото за издърпване не получава нищо. Но ако приложа същото със закъснение от 500 ms, то работи. - person user2449952; 21.08.2014
comment
И кодът ми работи, ако го напиша, за да внедря проста програма за обмен на естествено число дори с помощта на dontWait:true - person user2449952; 21.08.2014
comment
можете ли да качите кода? ако натискането е това, което свързва, не виждам причина да не работи, дори ако гнездото все още не е свързано (трябва да постави съобщението в опашка и да го изпрати, когато гнездото е свързано) - person somdoron; 21.08.2014
comment
Преди това ставаше много тромаво.. Публикувах го като отговор - person user2449952; 22.08.2014

въпросът е като

        using (NetMQContext ctx = NetMQContext.Create())
        {
            using (var publisher = ctx.CreatePushSocket())
            {

                publisher.Bind("tcp://localhost:5000");

                int i = 0;
                while (true)
                {
                    try
                    {

                        publisher.Send(i.ToString(), dontWait:true);
                        Console.WriteLine(i.ToString());
                    }
                    catch (Exception e)
                    {

                    }
                    finally
                    {
                        i++;
                    }

            }
        }

Сега този код работи. Но ако преместя своя цикъл while(true) навън. и извикайте този код от друга функция, която принуждава push socket и контекста да се създават като нови всеки път.. това не работи.

person user2449952    schedule 22.08.2014
comment
Братко, мисля, че след обвързването му трябва известно време. Така че, ако вляза в Thread.Sleep (200), той започна да работи. Но не разбирам причината. - person user2449952; 22.08.2014
comment
Във вашия пример с pubsub издателят е този, който се свързва, сега издателят прави свързването. ако издателят направи връзката, всичко ще работи добре. Сега проблемът е, че когато се свързвате, не можете да знаете кога някой ще се свърже, ако се опитвате да изпратите съобщение, докато няма други партньори, съобщението ще бъде премахнато. - person somdoron; 22.08.2014
comment
също така с NetMQ е по-добра практика да създадете контекста веднъж, също така създаването и разполагането на сокет на същия адрес за свързване много време не се препоръчва и вероятно няма да работи добре. Можете ли да го създадете веднъж за целия живот на системата? - person somdoron; 22.08.2014
comment
pushSocket трябва да се свързва нали? така че го правя по този начин. Второ, прочетох това нещо веднъж завинаги. Създадох контекст като статичен, но понякога дава грешка при обвързване. :( Въпреки че използвах terminate в Application_End - person user2449952; 22.08.2014
comment
Разрязването на Bind и Connect помогна на човека. Работи. Благодаря много - person user2449952; 22.08.2014