C# Nancy Async Beta的长轮询

C# Nancy Async Beta的长轮询,c#,async-await,long-polling,nancy,C#,Async Await,Long Polling,Nancy,通常我会使用signar来处理任何数据推送,但在本例中,我在服务器端使用Nancy Async Beta的自托管实例。我听说在这种情况下仍然可以使用SignalR,但在这种情况下,我仍然更愿意自己处理长轮询。下面是我正在编写的一个简单实验应用程序的代码,它产生了下面描述的问题: Get["/receivechat", true] = async (x, ct) => { string result = await _m

通常我会使用signar来处理任何数据推送,但在本例中,我在服务器端使用Nancy Async Beta的自托管实例。我听说在这种情况下仍然可以使用SignalR,但在这种情况下,我仍然更愿意自己处理长轮询。下面是我正在编写的一个简单实验应用程序的代码,它产生了下面描述的问题:

        Get["/receivechat", true] = async (x, ct) =>
            {
                string result = await _massPublisher.WaitForResult("test");
                return result;
            };
这将处理实际的长轮询请求。请求似乎以4或5的块形式输入这个lambda。例如,如果我在lambda的第一行放一个断点,我不会看到断点被击中,直到我再发送4或5个请求,然后突然所有的请求同时进入lambda。显然,我需要他们都按要求输入,这样他们都可以等待我的WaitForResult方法。WaitForResult方法只是等待一个公共TaskCompletionSource。如果需要,我可以发布该代码和客户端代码。据我所知,我使用Nancy Async Beta的方式似乎有问题,因为请求是并行处理的,在发出其他一些请求之前,请求甚至不会进入lambda

可能值得注意的是,在此期间,此应用程序仍对所有其他请求作出响应

我已经阅读了Nancy Async测试版上的我能找到的内容,看起来这个例子应该可以工作……但它不是——对我来说无论如何。如果有人能提供一些关于为什么这不起作用的见解,我们将不胜感激。就像我说的,我可以从这个实验中发布更多的代码,但现在看来,这只会把问题弄得一团糟

更新: 因为我对TPL和Nancy比较陌生,所以我将代码从实验中删除,以便隔离问题并进行更多的故障排除。这是我更新的代码。它只是等待5秒的任务延迟,然后将当前时间发送给客户端

        Get["/receivechat", true] = async (x, ct) =>
            {
                //string result = await _massPublisher.WaitForResult("test");
                //return result;
                await Task.Delay(5000);
                return DateTime.Now.ToString();
            };
我的理解是,每个请求都将被并行处理,并且相互独立。现在有了这样的理解,我认为无论有多少其他客户端轮询这些请求,每个客户端都应该每5秒看到一次回复。然而,结果如下:

换句话说,响应每5秒发送一次,但一次只发送给一个客户端。因此,对于3个客户端,每个客户端需要15秒才能收到响应。持续2=10秒等


到目前为止,我看不出我做错了什么。这就是我来这里的原因。我喜欢发现我错了!:)我要学点新东西。所以,如果你知道或者可能知道我哪里出了问题,请告诉我。我可能错过了一些我在寻找它的过程中忽略了的小而愚蠢的东西&希望这是一个其他人会发现有用的错误。

在史蒂文·罗宾斯非常感激的帮助下解决了这个问题。这是因为浏览器一次不发送多个挂起的请求,但我以前在所有浏览器上都看到过这种情况,包括我正在测试的Chrome。浏览器将与服务器建立多个并发连接,但这些请求必须是唯一的(显然)。如果Chrome看到一个挂起的请求与它将要发送的请求完全匹配,它将等待直到挂起的请求完成,从而产生问题中所示的精确输出,因为其他客户端是同一浏览器的多个窗口(请参见问题和说明中的图像)

因此,通过将JS的注释行(下面)改为上面的行(主要是为了修复缓存问题),它还修复了长轮询问题,我在问题中的两个示例突然都非常有效

            $.get("/receivechat?_=" + new Date().getTime(), null, function (data)
            //$.get("/receivechat", null, function (data)
            {
                self.viewModel.chatLines.push(data);
                self.update();
            }).error(function ()
            {
                setTimeout(self.update, 2000);
            });

异步代码中没有任何东西会导致这种行为,我们现在已经在多个地方进行了生产,所以我建议您测试它的方式,或者其他地方,可能有问题?嗨,史蒂文,我很确定我做错了什么。我不知道是什么原因,因为1)异步lambda只是在等待一个公共TaskCompletionSource,2)现在我正在使用两个断点(1个在lambda的开头,1个在等待之后)手动测试,这样我就可以看到什么&什么时候有东西进入/退出。我想我会发布一个简明的逐场测试。我注意到的另一件事是,这个例子可以很好地用于一个客户机,但不能用于多个客户机。我之前测试过4到5个客户,这次是3个。(很抱歉,我把这些都分解为每行一步,但stackoverflow显然不允许您在这些评论中这样做。可能与浏览器将发送到同一服务器的请求量有关?我们已经使用压力测试工具对数千个同时请求进行了测试,但没有看到这种行为。