JavaScript EventSource SSE未在浏览器中触发 [英] JavaScript EventSource SSE not firing in browser

查看:103
本文介绍了JavaScript EventSource SSE未在浏览器中触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在开发nodejs服务器,为我在HTML5中开发的新网站提供服务器端事件。

当我telnet到服务器时,正确地,给我发送所需的HTTP响应头文件,然后是一系列事件,我现在每2或3秒就会产生一次事件流,以证明它的正确性。

我试过了最新版本的FireFox,Chrome和Opera,它们创建EventSource对象并连接到nodejs服务器,但没有任何浏览器生成任何事件,包括onopen,onmessage和onerror。



但是,如果我停止了我的nodejs服务器,终止了来自浏览器的连接,它们都会突然发送所有消息,并显示我的所有事件。然后,浏览器都按照规范尝试重新连接到服务器。



我在网络服务器上托管所有内容。本地文件中没有任何内容正在运行。



我已经阅读了所有我可以在网上找到的东西,包括我购买的书籍,但没有任何内容显示任何此类问题。



示例服务器实现

  var http = require('http'); 
var requests = [];

var server = http.Server(function(req,res){
var clientIP = req.socket.remoteAddress;
var clientPort = req.socket.remotePort;

res.on('close',function(){
console.log(client+ clientIP +:+ clientPort +died);
$ b $ (请求[i] .ip == clientIP)&&(请求[i] .port(b)为(var i = requests.length -1; i> = 0; i--){
if == clientPort)){
requests.splice(i,1);
}
}
});

res.writeHead(200, {
'Content-Type':'text / event-stream',
'Access-Control-Allow-Origin':'*',
'Cache-Control':'no- cache',
'Connection':'keep-alive'});

requests.push({ip:clientIP,port:clientPort,res:res});

res.write(:connected.\\\
\\\
);
});

server.listen(8080);

setInterval(function test(){
broadcast('poll',test message);
},2000);

函数广播(rtype,msg){
var lines = msg.split(\\\
);

for(var i = requests.length -1; i> = 0; i--){
requests [i] .res.write(event:+ rtype + \\\
);
for(var j = 0; j if(lines [j]){
requests [i] .res.write(data:+行[j] +\\\
);
}
}
requests [i] .res.write(\\\
);





$ b

示例html页面

 <!DOCTYPE html> 
< html>
< head>
< title> SSE测试< /标题>
< meta charset =utf-8/>
< script language =JavaScript>
函数init(){
if(typeof(EventSource)!==undefined){
var log = document.getElementById('log');
if(log){
log.innerHTML =EventSource()测试开始..< br>;
}

var svrEvents = new EventSource('/ sse');

svrEvents.onopen = function(){
connectionOpen(true);
}

svrEvents.onerror = function(){
connectionOpen(false);
}

svrEvents.addEventListener('poll',displayPoll,false); //显示多项选择并回复答案

svrEvents.onmessage = function(event){
var log = document.getElementById('log');
if(log){
log.innerHTML + ='message:'+ event.data +< br>;
}
//吸收任何其他消息
}
} else {
var log = document.getElementById('log');
if(log){
log.innerHTML =EventSource()不支持< br>;




函数connectionOpen(status){
var log = document.getElementById('log');
if(log){
log.innerHTML + ='connected:'+ status +< br>;
}
}

函数displayPoll(event){
var html = event.data;
var log = document.getElementById('log');
if(log){
log.innerHTML + ='poll:'+ html +< br>;
}
}
< / script>
< / head>
< body onLoad =init()>
< div id =log>测试...< / div>
< / body>
< / html>

这些例子是基本的,但是与我在书籍和在线。如果我结束客户端连接或终止服务器,eventSource似乎只会工作,但这将是轮询而不是SSE,我特别想使用SSE。



有趣的是,如 html5rock 中的thouse演示,当我在线使用它们时,预期效果也不尽如人意。 。

解决方案

破解它! :)



感谢来自 Tom Kersten 帮助我进行测试。发现代码不是问题。



请注意..如果您的客户端使用任何拦截Web请求的防病毒软件,可能会导致问题。在这种情况下,提供企业级防病毒和防火墙保护的Sophos Endpoint Security具有一项称为Web保护的功能。在这个功能中可以选择扫描下载;似乎SSE连接被视为下载,因此在连接关闭并接收到扫描流之前,不会发布到浏览器。禁用此选项可以解决问题。我已经提交了一个错误报告,但其他反病毒系统可能也会这样做。

感谢您的建议,并帮助每个人:)

I have been developing a nodejs server to provide server-side-events for a new website I am developing in HTML5.

When I telnet to the server it works correctly, sending me the required HTTP response headers followed by a stream of events that i am presently generating every 2 or 3 seconds just to prove it works.

I have tried the latest version of FireFox, Chrome and Opera and they create the EventSource object and connect to the nodejs server OK but none of the browsers generate any of the events, including the onopen, onmessage and onerror.

However, if I stop my nodejs server, terminating the connection from the browsers, they all suddenly dispatch all the messages and all my events are shown. The browsers then all try to reconnect to the server as per spec.

I am hosting everything on a webserver. nothing is running in local files.

I have read everything I can find online, including books I've purchased and nothing indicates any such problem. Is there something Im missing?

A sample server implementation

  var http = require('http');
  var requests = [];

  var server = http.Server(function(req, res) {
    var clientIP = req.socket.remoteAddress;
    var clientPort = req.socket.remotePort;

    res.on('close', function() {
      console.log("client " + clientIP + ":" + clientPort + " died");

      for(var i=requests.length -1; i>=0; i--) {
        if ((requests[i].ip == clientIP) && (requests[i].port == clientPort)) {
          requests.splice(i, 1);
        }
      }
    });

    res.writeHead(200, {
      'Content-Type': 'text/event-stream', 
      'Access-Control-Allow-Origin': '*', 
      'Cache-Control': 'no-cache', 
      'Connection': 'keep-alive'});

    requests.push({ip:clientIP, port:clientPort, res:res});

    res.write(": connected.\n\n");
  });

  server.listen(8080);

  setInterval(function test() {
    broadcast('poll', "test message");
  }, 2000);

function broadcast(rtype, msg) {
  var lines = msg.split("\n");

  for(var i=requests.length -1; i>=0; i--) {
    requests[i].res.write("event: " + rtype + "\n");
    for(var j=0; j<lines.length; j++) {
      if (lines[j]) {
        requests[i].res.write("data: " + lines[j] + "\n");
      }
    }
    requests[i].res.write("\n");
  }
}

A sample html page

<!DOCTYPE html>
<html>
  <head>
    <title>SSE Test</title>
    <meta charset="utf-8" />
    <script language="JavaScript">
      function init() {
        if(typeof(EventSource)!=="undefined") {
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML = "EventSource() testing begins..<br>";
          }

          var svrEvents = new EventSource('/sse');

          svrEvents.onopen = function() {
            connectionOpen(true);
          }

          svrEvents.onerror = function() {
            connectionOpen(false);
          }

          svrEvents.addEventListener('poll', displayPoll, false);             // display multi choice and send back answer

          svrEvents.onmessage = function(event) {
              var log = document.getElementById('log');
              if (log) {
                log.innerHTML += 'message: ' + event.data + "<br>";
              }
            // absorb any other messages
          }
        } else {
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML = "EventSource() not supported<br>";
          }
        }
      }

      function connectionOpen(status) {
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML += 'connected: ' + status + "<br>";
          }
      }

      function displayPoll(event) {
        var html = event.data;
          var log = document.getElementById('log');
          if (log) {
            log.innerHTML += 'poll: ' + html + "<br>";
          }
      }
    </script>
  </head>
  <body onLoad="init()">
    <div id="log">testing...</div>
  </body>
</html>

These examples are basic but of the same variety as every other demo i've seen in books and online. The eventSource only seems to be working if I end a client connection or terminate the server but this would be polling instead of SSE and I particularly want to use SSE.

Interestingly, demos, such as thouse from html5rock also seem to not quite work as expected when I use them online..

解决方案

cracked it! :)

Thanks to some help from Tom Kersten who helped me with testing. Turns out the code isnt the problem.

Be warned.. if your client uses any kind of anti-virus software which intercepts web requests, it may cause problems here. In this case, Sophos Endpoint Security, which provides enterprise grade anti-virus and firewall protection has a feature called web protection. Within this features is an option to scan downloads; it seems that the SSE connection is treated as a download and thus not released to the browser until the connection is closed and the stream received to scan. Disabling this option cures the problem. I have submitted a bug report but other anti-virus systems may do the same.

thanks for your suggestions and help everyone :)

这篇关于JavaScript EventSource SSE未在浏览器中触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆