0

我正在尝试使用服务器发送的事件,以便我的网页可以从我的服务器定期更新。问题是我的客户端能够与我的服务器交互,但是,我的服务器的响应没有发送到我的客户端?基本上,当我用 Firefox 打开我的 html 文件时,我知道我的服务器收到了请求,然后它开始发送响应,但我的网页上没有显示任何内容......不太确定是什么问题。帮助表示赞赏!

这是我的客户代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
</head>
  <script>
     function init(){ 
      if(typeof(EventSource)!=="undefined"){
        var source = new EventSource('localhost');
        source.onmessage = function(e) {
        document.body.innerHTML += e.data + '<br>';
        };
      }
      else{
        document.body.innerHTML = "Sorry, your browser does not support server-sent events...";
      }
    }
  </script>
<body onload="init()">
</body>
</html>

这是我的服务器代码(node.js):

var http = require('http');
var sys = require('sys');
var fs = require('fs');

http.createServer(function(req, res) {

  if (req.headers.accept && req.headers.accept == 'text/event-stream') {
      sendSSE(req, res);
}).listen(80, "127.0.0.1");

function sendSSE(req, res) {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  var id = (new Date()).toLocaleTimeString();

  // Sends a SSE every 5 seconds on a single connection.
  setInterval(function() {
    constructSSE(res, id, (new Date()).toLocaleTimeString());
  }, 5000);
}

function constructSSE(res, id, data) {
  res.write('id: ' + id + '\n');
  res.write("data: " + data + '\n\n');
  }
4

2 回答 2

0

您需要添加

res.end();

某处并删除'setInterval'。但是,看起来您正在尝试做的是保持连接处于活动状态,在这种情况下,您需要显着更改代码。查看“net”模块,该模块更多地是为“恒定开启”交互式连接类型而设计的。

http://nodejs.org/api/net.html#net_net

http 模块专为有限的数据交换、请求类型而设计。你试图让它做一些它不打算做的事情。

/*jshint node:true */
var http = require('http');

http.createServer(function (req, res) {
    'use strict';
    console.log('GOOD request recieved');
    res.write('hi there');
    res.end();
    console.log('GOOD end sent');
}).listen(8888);

http.createServer(function (req, res) {
    'use strict';
    console.log('BAD request received');
    res.write('hi there');
    console.log('BAD response wrote not ending');
}).listen(8889);

考虑我上面的两台服务器。如果您使用节点客户端代码对它们进行 ping 操作,您将看到数据进入两者,并且在发送时应该看到块。但是,如果您尝试使用浏览器 ping 8889,则网页将永远不会呈现,因为 end 事件永远不会发送。浏览器依靠它来知道所有内容都已被接收。如果您的客户端代码在浏览器中工作,这可能会影响事情。尝试首先对您的服务器使用普通的 NodeJS 客户端代码,并确保数据以您期望的方式发送。然后努力弄清楚浏览器是如何扰乱事物的。我的猜测是浏览器接收到数据,但它从来没有对它做任何事情,而是坐下来等待为那个“结束”事件分发它,就像 8889 服务器的网页从不呈现一样......

示例客户端代码:

var options = {
    hostname: '127.0.0.1',
    method: 'GET'
};

options.port = 8888;

http.request(options, function (res) {
    'use strict';

    console.log('GOOD Pinged server');

    res.on('data', function (chunk) {
        console.log('GOOD data chunk:' + chunk);
    });

    res.on('end', function () {
        console.log('GOOD end event recieved');
    });
}).end();

options.port = 8889;

http.request(options, function (res) {
    'use strict';
    console.log('BAD Pinged server');

    res.on('data', function (chunk) {
        console.log('BAD data chunk:' + chunk);
    });

    res.on('end', function () {
        console.log('BAD end event recieved');
    });
}).end();
于 2013-07-03T17:31:40.783 回答
0

node 中的 http 模块适用于 Server Sent Events,并且 Node SSE 的大多数演示代码都使用它。但是你必须小心一些陷阱。

我被打开压缩了。解决方案是在每条数据消息res.flush()的最后一个之后添加。res.write()因为这很容易解决,所以我会先尝试一下,然后再使用不同的模块进行重写。

于 2014-09-30T15:18:47.787 回答