为什么这个EventSource会重复触发消息和错误?

客户端看起来像这样:

var es = new EventSource("http://localhost:8080"); es.addEventListener("message", function(e) { alert("e.data") //Alerts "" every couple seconds }) es.addEventListener("error", function(e) { alert("error") //Also fires every couple of seconds }) var post_request = new XMLHttpRequest(); post_request.open("POST", "http://localhost:8080"); post_request.setRequestHeader("Content-Type", "text/plain"); post_request.addEventListener("readystatechange", function() { if (post_request.readyState == 4 && post_request.status == 200) { alert(post_request.responseText); //This works } }) post_request.send("This is a test") 

处理POST请求的服务器端Node.js如下所示:

 function process_request(request, response) { var request_body = [] request.on("data", function(chunk) { request_body.push(chunk) }) request.on("end", function() { request_body = Buffer.concat(request_body).toString()+"\n" response.writeHead(200, {"Access-Control-Allow-Origin": "*", "Content-Type": "text/event-stream", "Connection": "keep-alive" }); response.end("data: " + request_body + "\n"); }) } 

如果我从客户端发送POST请求数据,它将按照预期的方式返回给我response.end() ,但是es每隔几秒触发一个错误,除了每两秒钟发生一次message事件。 但是,当message事件被触发时,它会提醒"" ,我不知道为什么? 任何人都可以帮我弄清楚这种行为?

编辑:只检查了es.readyState messageerror事件。 readyStateerror上是0 ,所以看起来好像可能是断开连接的结果。 为什么会发生这种重复的断开连接? 为什么重复连接和断开会导致重复的message事件?

发生什么事是你正在处理用户的SSE请求,发回一些数据,然后closures连接。 客户端看到连接已经丢失,几秒钟后重新连接(这个重新连接是SSE的一个特性)。

所以,相反,你永远不应该退出。 这意味着你需要确保request.on("end", ...永远不会到达。

以下是我以前使用的node.js中的基本SSE服务器:

 var http = require("http"); var port = parseInt( process.argv[2] || 8080 ); http.createServer(function(request,response){ console.log("Client connected:" + request.url); response.writeHead(200, { "Content-Type": "text/event-stream" }); var timer = setInterval(function(){ var content = "data:" + new Date().toISOString() + "\n\n"; response.write(content); }, 1000); request.connection.on("close", function(){ response.end(); clearInterval(timer); console.log("Client closed connection. Aborting."); }); }).listen(port); console.log("Server running at http://localhost:" + port); 

即我们使用setInterval来继续运行。 唯一要监听的事件是closures连接的客户端。

Interesting Posts