-1

This implementation is bad since it will end up disposing the SubscriberSocket when the first subscription terminates. When I run it, nothing seems to publish. [This uses Rx 3.0.0]

How to modify Receive function to fix this problem?

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;

using NetMQ;
using NetMQ.Sockets;

using System.Reactive.Linq;

namespace App1
{
    class MainClass
    {
        // publisher for testing, should be an external data publisher in real environment
        public static Thread StartPublisher(PublisherSocket s)
        {
            s.Bind("inproc://test");
            var thr = new Thread(() =>
            {
                Console.WriteLine("Start publishing...");
                while (true)
                {
                    Thread.Sleep(500);
                    bool more = false;
                    s.SendFrame("hello", more);
                }
            });

            thr.Start();
            return thr;
        }

        public static IObservable<string> Receive(SubscriberSocket subp)
        {
            return Observable
                .Create<string>(o =>
                    Observable.Using<string, SubscriberSocket>(() =>
                    {
                        subp.Connect("inproc://test");
                        subp.Subscribe("");
                        return subp;
                    }, sub =>
                        Observable
                        .FromEventPattern<EventHandler<NetMQSocketEventArgs>, NetMQSocketEventArgs>(
                            h => sub.ReceiveReady += h,
                            h => sub.ReceiveReady -= h)
                         .Select(x => sub.ReceiveFrameString()))
                .Subscribe(o));
        }

        public static void Main(string[] args)
        {
            var sub = new SubscriberSocket();
            var pub = new PublisherSocket();

            StartPublisher(pub);
            Receive(sub).Subscribe(Console.WriteLine);

            Console.ReadLine();
        }
    }
}
Ivan
  • 7,448
  • 14
  • 69
  • 134

1 Answers1

0

It seems to me that you should be doing something like this:

void Main()
{
    var address = "inproc://test";

    var pub = new PublisherSocket();
    pub.Bind(address);

    var pubSubscription =
        Observable
            .Interval(TimeSpan.FromMilliseconds(500.0))
            .Subscribe(n => pub.SendFrame("hello", false));

    Receive(address).Subscribe(Console.WriteLine);

    Console.ReadLine();
}

public static IObservable<string> Receive(string address)
{
    return Observable
        .Create<string>(o =>
            Observable.Using<string, SubscriberSocket>(() =>
            {
                var ss = new SubscriberSocket();
                ss.Connect(address);
                ss.Subscribe("");
                return ss;
            }, ss =>
                Observable
                .FromEventPattern<EventHandler<NetMQSocketEventArgs>, NetMQSocketEventArgs>(
                    h => ss.ReceiveReady += h,
                    h => ss.ReceiveReady -= h)
                 .Select(x => ss.ReceiveFrameString()))
        .Subscribe(o));
}

Primarily, this means creating the SubscriberSocket inside the Observable.Create - which is where it belongs.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • Nothing prints in this program though? – Ivan Oct 18 '17 at 20:35
  • I included everything from the code you posted. Does your code print anything? Can you ensure that your code is a [mcve] - one that I can copy, paste, and run? Please let me know what references to add too. Then I can test my code. – Enigmativity Oct 18 '17 at 21:08