客户端始终响应先前服务器发送的事件,而不是当前事件

Zev*_*itz 8 javascript asp.net-mvc server-sent-events

我看到的代码古怪的行为在这里.

客户端(Javascript):

<input type="text" id="userid" placeholder="UserID" /><br />`  
<input type="button" id="ping" value="Ping" />

<script>
    var es = new EventSource('/home/message');
    es.onmessage = function (e) {
        console.log(e.data);
    };
    es.onerror = function () {
        console.log(arguments);
    };
    $(function () {
        $('#ping').on('click', function () {
            $.post('/home/ping', {
                UserID: parseInt($('#userid').val()) || 0
            });
        });
    });
</script>
Run Code Online (Sandbox Code Playgroud)

服务器端(C#):

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Web.Mvc;
using Newtonsoft.Json;

namespace EventSourceTest2.Controllers {
    public class PingData {
        public int UserID { get; set; }
        public DateTime Date { get; set; } = DateTime.Now;
    }

    public class HomeController : Controller {
        public ActionResult Index() {
            return View();
        }  

        static ConcurrentQueue<PingData> pings = new ConcurrentQueue<PingData>();

        public void Ping(int userID) {
            pings.Enqueue(new PingData { UserID = userID });
        }

        public void Message() {
            Response.ContentType = "text/event-stream";
            do {
                PingData nextPing;
                if (pings.TryDequeue(out nextPing)) {
                    var msg = "data:" + JsonConvert.SerializeObject(nextPing, Formatting.None) + "\n\n";
                    Response.Write(msg);
                }
                Response.Flush();
                Thread.Sleep(1000);
            } while (true);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

一旦我按下ping以向pings队列添加新项目,Message方法内的循环就会选择新项目并通过Response.Write(在服务器上使用Debug.Print确认)发出事件.但是,在onmessage我第二次按ping之前,浏览器不会触发,浏览器会发出另一个事件; 此时来自第一个事件的数据到达onmessage.

我怎样才能解决这个问题?


澄清一下,这是我期望的行为:

Client                       Server
-------------------------------------------------------------------
Press Ping button
XHR to /home/ping
                             Eneque new item to pings
                             Message loop issues server-sent event
EventSource calls onmessage
Run Code Online (Sandbox Code Playgroud)

这是实际发生的事情:

Client                       Server
-------------------------------------------------------------------
Press Ping button
XHR to /home/ping
                             Eneque new item to pings
                             Message loop issues server-sent event
(Nothing happens)
Press Ping button again
New XHR to /home/ping
EventSource calls onmessage with previous event data
Run Code Online (Sandbox Code Playgroud)

(在Chrome中运行时,message请求在"网络"标签中列为始终处于待处理状态.我不确定这是否是服务器发送事件的正常行为,或者可能与问题有关.)

编辑

msg变量的字符串表示形式Response.Write如下所示:

"data:{\"UserID\":105,\"Date\":\"2016-03-11T04:20:24.1854996+02:00\"}\n\n"
Run Code Online (Sandbox Code Playgroud)

非常清楚地包括换行符.

Jua*_*uan 0

我不确定这是否有效,因为我现在无法尝试,但是添加一个 End 怎么样?:

Response.Flush();
Response.End();
Run Code Online (Sandbox Code Playgroud)