richardschneider / net-ipfs-http-client

InterPlanetary File System client for .Net (C#, VB, F# ...)
MIT License
158 stars 52 forks source link

Subscribing to more than 2 topics #34

Closed xuzhe35 closed 6 years ago

xuzhe35 commented 6 years ago

Using Api to execute IPFS.PubSub.Sub

we can only get no more than two topics

if we run

ipfs.pubsub.sub 111 ipfs.pubsub.sub 222 ipfs.pubsub.sub 333 ipfs.pubsub.sub 444

we can only see two of them

111 and 222

xuzhe35 commented 6 years ago

it works when i put commands to browser(Chrome)

we can use pubsub ls

there are 4 topics all of them

xuzhe35 commented 6 years ago

` string strChannelID = txtTopics.Text;

        new Task(async () =>
        {
            await GUID.ipfs.PubSub.Subscribe(strChannelID, (msg) =>
            {
                string strShow = Encoding.UTF8.GetString(msg.DataBytes);
                MessageBox.Show(strShow);

            }, new System.Threading.CancellationToken());

            MessageBox.Show(strChannelID + "Subscribed");
        }).Start();`

i test again and again

it will not work if there are more than two topics

richardschneider commented 6 years ago

Thanks for the bug report. I'll create some test multiple subscribes and get back to you.

richardschneider commented 6 years ago

I've added the test Subscribe_Multiple_Topics() and everything is passing!

It's been tested against go-ipfs v0.4.17. Please note that earlier versions had various pubsub issues with windows.

Can you give more details and/or show a repo that exhibits the issue.

xuzhe35 commented 6 years ago

thanks for replying

i update my go-ipfs on Windows,it's v0.4.17 now

and i write some simple code

            for (int i = 1; i <= 4; i++)
            {
                var top_id = "topic_" + i.ToString();
                try
                {
                    await GUID.ipfs.PubSub.Subscribe(top_id, (msg) =>
                    {
                        Console.WriteLine(Encoding.UTF8.GetString(msg.DataBytes));
                    }, new CancellationToken());

                    MessageBox.Show("Finish once:" + top_id);
                }
                catch(Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
                finally { }
            }

still just for twice.

MessageBox show finish 1st and 2nd topic subscribe,but no work for 3rd topic and no exception catched

it's strange

xuzhe35 commented 6 years ago

And your test passed .

I'm confused

xuzhe35 commented 6 years ago

In TestMethod

it works for 4 times

same code in WinForm application doesn't work, always failed in 3rd time.

richardschneider commented 6 years ago

You are most likely encountering "cross thread issues". The callback/action is is run on a non-UI thread when a topic message is received.

Please create a github repo that has the failing code. I will fork it and try to make it work.

xuzhe35 commented 6 years ago

To avoid WinForm CrossThread problem

i create a very simple test console app.

here's the whole code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ipfs;
using Ipfs.Api;

namespace SubTest
{
    class Program
    {
        static void Main(string[] args)
        {
            IpfsClient client = new IpfsClient();

            for (int i = 0; i < 4; ++i)
            {
                string topic_id = "topic_" + i.ToString();
                client.PubSub.Subscribe(topic_id, msg =>
                 {
                     Console.WriteLine("[{0}]:{1}", topic_id, Encoding.UTF8.GetString(msg.DataBytes));
                 }, new System.Threading.CancellationToken());
            }

            Console.ReadKey();
        }
    }
}

when i use command

ipfs pubsub ls

there are only two topics

topic_0 topic_1

Thanks a lot

richardschneider commented 6 years ago

Thanks, it is a nice simple example. When running the example and then doing ipfs pubsub ls I get all four topics displayed!

Can you make sure that you are using the latest (v0.4.17) of go-ipfs. There's been various fixes to the pubsub logic.

choco upgrade go-ipfs from an admin console.

xuzhe35 commented 6 years ago

Yes,i am sure i am using the version 0.4.17

ipfs version return ipfs version 0.4.17

i am so confused now

xuzhe35 commented 6 years ago

i use another laptop computer and run your test

still

> ipfs pubsub ls
net-ipfs-api-test-4e27604c-f841-4f9f-9c39-b62ea1aa82b6
net-ipfs-api-test-883ee247-1f0d-4e6d-a794-91ebcaca6408

can only get two topics and the test run for very long time and fail.

richardschneider commented 6 years ago

I am also confused. Can you show the test log failure?

xuzhe35 commented 6 years ago

测试名称: Subscribe_Multiple_Topics 测试全名: Ipfs.Api.PubSubApiTest.Subscribe_Multiple_Topics 测试源: C:\Users\xuzhe\Downloads\net-ipfs-api-master\test\CoreApi\PubSubApiTest.cs:第 178 行 测试结果: 未通过 测试持续时间: 0:01:41.5627695

结果 的堆栈跟踪:
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter1.GetResult() 在 Ipfs.Api.IpfsClient.<PostDownloadAsync>d__87.MoveNext() 位置 C:\Users\xuzhe\Downloads\net-ipfs-api-master\src\IpfsClient.cs:行号 333 --- 引发异常的上一位置中堆栈跟踪的末尾 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter1.GetResult() 在 Ipfs.Api.PubSubApi.d6.MoveNext() 位置 C:\Users\xuzhe\Downloads\net-ipfs-api-master\src\CoreApi\PubSubApi.cs:行号 53 --- 引发异常的上一位置中堆栈跟踪的末尾 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.GetResult() 在 Ipfs.Api.PubSubApiTest.d10.MoveNext() 位置 C:\Users\xuzhe\Downloads\net-ipfs-api-master\test\CoreApi\PubSubApiTest.cs:行号 201 --- 引发异常的上一位置中堆栈跟踪的末尾 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.ThreadOperations.ExecuteWithAbortSafety(Action action) 结果 的消息: 测试方法 Ipfs.Api.PubSubApiTest.Subscribe_Multiple_Topics 引发了异常: System.Threading.Tasks.TaskCanceledException: 已取消一个任务。 结果 的标准输出:
2018/08/15 16:17:05:169 [DEBUG] Ipfs.Api.IpfsClient - POST http://localhost:5001/api/v0/pubsub/sub?arg=net-ipfs-api-test-4e27604c-f841-4f9f-9c39-b62ea1aa82b6 2018/08/15 16:17:06:446 [DEBUG] Ipfs.Api.IpfsClient - POST http://localhost:5001/api/v0/pubsub/sub?arg=net-ipfs-api-test-883ee247-1f0d-4e6d-a794-91ebcaca6408 2018/08/15 16:17:06:446 [DEBUG] Ipfs.Api.PubSubApi - Start listening for 'net-ipfs-api-test-4e27604c-f841-4f9f-9c39-b62ea1aa82b6' messages 2018/08/15 16:17:06:447 [DEBUG] Ipfs.Api.IpfsClient - POST http://localhost:5001/api/v0/pubsub/sub?arg=net-ipfs-api-test-aec892bb-2969-47ba-a4ab-400d69ed9522 2018/08/15 16:17:06:447 [DEBUG] Ipfs.Api.PubSubApi - Start listening for 'net-ipfs-api-test-883ee247-1f0d-4e6d-a794-91ebcaca6408' messages 2018/08/15 16:18:46:519 [DEBUG] Ipfs.Api.PubSubApi - Stop listening for 'net-ipfs-api-test-4e27604c-f841-4f9f-9c39-b62ea1aa82b6' messages 2018/08/15 16:18:46:520 [DEBUG] Ipfs.Api.PubSubApi - Stop listening for 'net-ipfs-api-test-883ee247-1f0d-4e6d-a794-91ebcaca6408' messages

xuzhe35 commented 6 years ago

when i copy http://localhost:5001/api/v0/pubsub/sub?arg=net-ipfs-api-test-4e27604c-f841-4f9f-9c39-b62ea1aa82b6

http://localhost:5001/api/v0/pubsub/sub?arg=net-ipfs-api-test-883ee247-1f0d-4e6d-a794-91ebcaca6408

http://localhost:5001/api/v0/pubsub/sub?arg=net-ipfs-api-test-aec892bb-2969-47ba-a4ab-400d69ed9522

to chrome

pubsub ls shows it success,there are 3 topics as excepted

for some unknown reason, the third POST request timeout.

xuzhe35 commented 6 years ago

Interesting thing

same code

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        new Task(async () =>
        {
            var topicCount = 10;
            var topics = new string[topicCount];
            var cancels = new CancellationTokenSource[topicCount];
            Ipfs.Api.IpfsClient ipfs = new Ipfs.Api.IpfsClient();
            for (int i = 0; i < topicCount; ++i)
            {
                topics[i] = "net-ipfs-api-test-" + Guid.NewGuid().ToString();
                cancels[i] = new CancellationTokenSource();
            }

            try
            {
                // Subscribe to N topics.
                for (int i = 0; i < topicCount; ++i)
                {
                    await ipfs.PubSub.Subscribe(topics[i], msg =>
                    {
                        Console.WriteLine($"{msg.Sender}|{msg.Topics}|{Encoding.UTF8.GetString(msg.DataBytes)}");
                    }, cancels[i].Token);
                }
                // Verify topics.
                var actualTopics = await ipfs.PubSub.SubscribedTopicsAsync();

                foreach (var item in actualTopics)
                {
                    Console.WriteLine($"{item}");

                }

                // Publish a message to each topic.
                for (int i = 0; i < topicCount; ++i)
                {
                    await ipfs.PubSub.Publish(topics[i], "hello world!");
                }
                // Verify that all messages have been received.
                await Task.Delay(1000);
            }
            finally
            {
                //foreach (var cs in cancels)
                //{
                //    cs.Cancel();
                //}
            }
        }).Start();

        Console.ReadKey();
    }
}

works very well in a Console Application or TestProject

but only can sub no more than 2 topics under WinForm or WPF project

And i use HttpClient repleace WebRequest Class,it works well

i can not explain

richardschneider commented 6 years ago

Could it be that HttpClient is limiting the number of concurrent requests on certain platforms?

richardschneider commented 6 years ago

This may be of help https://github.com/dotnet/corefx/issues/2332

xuzhe35 commented 6 years ago

It's highly possible

i will do more tests

richardschneider commented 6 years ago

I'm closing this issue because you cannot show any failure. Please open another issue if you can show me a full repo the exhibits the problem.