.Net 服务器使用 HttpHandler 发送的事件不起作用

问题描述 投票:0回答:2

我一直在尝试实现向客户端浏览器的事件驱动推送。我正在使用 ReactiveX 从事件中生成异步任务,但我什至无法让我的 HttpHandler 输出其响应。

我尝试过使用简单的 HttpHandler:

public class Handler2 : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/event-stream";
        HttpResponse response = context.Response;

        DateTime startdate = DateTime.Now;

        while (startdate.AddMinutes(10) > DateTime.Now)
        {
            JavaScriptSerializer js = new JavaScriptSerializer();

            string responseText = DateTime.Now.TimeOfDay.ToString();

            response.Write(string.Format("data: {0}",js.Serialize(responseText)));
            response.Flush();
            System.Threading.Thread.Sleep(1000);
        }
        response.Close();
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

使用以下客户端代码:

function initialize() {

    if (window.EventSource == undefined) {
        document.getElementById('targetDiv').innerHTML = "Your browser doesn't support Server Side Events.";
        return;
    }

    var source = new EventSource('Handler2.ashx');

    source.onopen = function (event) {
        document.getElementById('targetDiv').innerHTML += 'Connection Opened.<br>';
    };

    source.onerror = function (event) {
        if (event.eventPhase == EventSource.CLOSED) {
            document.getElementById('targetDiv').innerHTML += 'Connection Closed.<br>';
        }
    };

    source.onmessage = function (event) {
        document.getElementById('targetDiv').innerHTML += event.data + '<br>';
    };
}

我有一个更复杂的 HttpTaskAsyncHandler 准备连接,但我什至无法让它工作 >_< I get the Connection Opened message, Handler2.ashx appears to remain connected (Looking at Chrome dev tools / Network).

另一方面,我正在从 SignalR 连接获取一些数据?

"ws://localhost:50022/ed4b66c7eb394a8789b5f6a631f4ff09/arterySignalR/connect?.."

我设置错了吗? 据我在其他示例中看到的,这段代码应该按原样工作。请任何人帮助我。我只想要一个可以从服务器端事件触发的简单 SSE 控件。

提前致谢

asp.net html httphandler server-sent-events
2个回答
0
投票

我之前已经给出过这个答案,但让我详细说明一下:

查看 Google Chrome 开发者工具中的“网络”选项卡,可以从您的 http://live.meetscoresonline.com/test-sse.aspx

中了解很多信息

根本没有生成 SSE - 要查看此内容,请单击“网络”下的“其他”按钮,您通常可以在此处跟踪 SSE 数据流

我在 SSE 中使用以下代码和一个简单的 HTTPListener,它运行良好,没有您提到的延迟,并且在使用此 polyfill

时始终在浏览器中正确显示
        res.AddHeader("Content-Type", "text/event-stream")
        res.AddHeader("Cache-Control", "no-cache")
        res.AddHeader("Access-Control-Allow-Origin", "*")
        res.KeepAlive = True

0
投票

对于遇到相同问题的任何人,请确保遵循 SSE 要求的确切格式:

数据:我的数据内容在这里

前缀“data:”很重要,末尾的 2 个换行符也很重要。 否则,客户端将永远不会收到事件。

以下是该标准的描述: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

另外,不要关闭响应,保持打开状态,直到您想要停止发送事件为止。

所以,从原来的帖子:

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/event-stream";
    HttpResponse response = context.Response;
    response.KeepAlive = true; // i think this already defaults to true though
    DateTime startdate = DateTime.Now;

    while (startdate.AddMinutes(10) > DateTime.Now)
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        string responseText = DateTime.Now.TimeOfDay.ToString();
        
        // If it's just plain text, you can actually use: Encoding.ASCII.GetBytes($"data:{responseText}\n\n");
        response.Write(string.Format("data: {0}\n\n",js.Serialize(responseText)));
        response.Flush();
        System.Threading.Thread.Sleep(1000);
    }
    response.Close();
}
© www.soinside.com 2019 - 2024. All rights reserved.