标签: server-sent-events

Server-Sent-Events如何工作

我在tomcat 8.0上使用java尝试了SSE(Server-Sent-Events).以下是我注意到的一些事情.

我单击一个自动向servlet发出请求的按钮.执行Servlet的GET方法,返回事件流.收到完整的流后,页面会再次自动发出另一个请求,再次接收相同的数据!我没有无限循环!!!

  1. 服务器上实际发生了什么?在正常情况下,tomcat会创建一个线程来处理每个请求.现在发生了什么?

  2. 确保事件流只发送一次到同一个连接/浏览器会话的正确方法是什么?

  3. 确保事件流关闭且服务器上不会产生资源开销的正确方法是什么?

  4. 如何区分GET和POST请求.为什么选择GET?

  5. 在Tomcat上使用SSE为时尚早?任何性能问题?

这是好奇的代码,

@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //content type must be set to text/event-stream
        response.setContentType("text/event-stream"); 
        //cache must be set to no-cache
        response.setHeader("Cache-Control", "no-cache");     
        //encoding is set to UTF-8
        response.setCharacterEncoding("UTF-8");

        PrintWriter writer = response.getWriter();

        for(int i=0; i<10; i++) {
            System.out.println(i);
            writer.write("data: "+ i +"\n\n");
            writer.flush();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        writer.close(); 
    }
}
Run Code Online (Sandbox Code Playgroud)

页面上的Javascript(页面上没有其他内容),

<button onclick="start()">Start</button> …
Run Code Online (Sandbox Code Playgroud)

java tomcat server-sent-events tomcat8

15
推荐指数
1
解决办法
2万
查看次数

在浏览器中调试HTML5 Server-Sent事件

有没有办法在Chrome(或Firefox)中查看/调试Server-Sent Events?我希望他们出现在Chrome开发者工具的网络标签中.我所知道的最接近的方式是下载到Wireshark,但相比之下这相当麻烦.

例如,请访问http://www.emojitracker.com/.您将看到使用服务器中的数据实时更新页面,但网络选项卡中不显示任何活动.(它在/application.js的第97行订阅服务器事件.)

debugging html5 google-chrome server-sent-events

14
推荐指数
2
解决办法
8202
查看次数


HTML5 Server-Sent Events原型设计 - 模糊错误和重复轮询?

我想它们符合我的要求完美,看起来他们应该是简单的实现获得与服务器端事件交手,但我不能让过去一个模糊的错误,什么样子反复被关闭了连接并重新-opened.我尝试的一切都基于这个和其他教程.

PHP是一个单独的脚本:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

function sendMsg($id, $msg) {
  echo "id: $id" . PHP_EOL;
  echo "data: $msg" . PHP_EOL;
  echo PHP_EOL;
  ob_flush();
  flush();
}

$serverTime = time();
sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));
?>
Run Code Online (Sandbox Code Playgroud)

并且JavaScript看起来像这样(在身体负载上运行):

function init() {

    var source;
    if (!!window.EventSource) {
        source = new EventSource('events.php');
        source.addEventListener('message', function(e) {
            document.getElementById('output').innerHTML += e.data + '<br />';
        }, false);
        source.addEventListener('open', function(e) {
            document.getElementById('output').innerHTML += 'connection opened<br />';
        }, false);
        source.addEventListener('error', function(e) {
            document.getElementById('output').innerHTML += 'error<br />'; …
Run Code Online (Sandbox Code Playgroud)

apache html5 server-push server-sent-events

13
推荐指数
1
解决办法
1万
查看次数

有jQuery EventSource吗?

Server Sent Events似乎是jQuery插件的主要候选者."权威指南"第921页显示了如何使用EventSource.但是后来第923页说IE使用attachEvent而不是addEventListener.

我在github上找到了jQuery.EventSource,但是没有提到attachEvent.它反过来使用$ .ajax.

问:如果我要使用JavaScript的EventSource功能,我应该使用jQuery.EventSource吗?

我必须有更多的jQuery!

javascript jquery server-sent-events

13
推荐指数
1
解决办法
1万
查看次数

Python Flask,如何从前端Javascript检测SSE客户端断开连接

也许这是Flask的一个问题,没有办法在服务器端处理断开连接事件.

在Response类中,有一个名为"call_on_close"的方法,我们可以在其中添加一个没有参数的函数,例如on_close(),它会在响应对象的close方法被调用时触发,但是当我调用EventSource时这不会发生.在Javascript中从客户端关闭().

服务器端的代码:

from flask import Response
r = Response(stream(), ...)
r.call_on_close(on_close)
return r 

def on_close():
  print "response is closed!"

def stream():
  ...  # subscribe to redis
  for message in pubsub.listen():
    ....
    yield 'data: %s\n\n' % message
Run Code Online (Sandbox Code Playgroud)

在客户端:使用SSE向页面添加卸载处理程序

$(window).unload(
  function() {
    sse.close();
  }
}
Run Code Online (Sandbox Code Playgroud)

什么都错了?

任何建议或解决方案与代码表示赞赏!

提前致谢!

python flask server-sent-events

13
推荐指数
2
解决办法
2091
查看次数

具有服务器发送事件的AngularJS

我有一个带有以下控制器的AngularJS应用程序.它可以在常规JSON资源和手动更新请求上使用GET,但我无法使用Server-Sent Events.我面临的问题是,在收到SSE事件并设置/更新openListingsReport变量后,我的视图没有得到更新.我显然错过了一个非常基本的概念.请帮我解决这个问题.

var rpCtrl = angular.module('rpCtrl', ['rpSvc']);

rpCtrl.controller('rpOpenListingsCtrl', ['$scope', 'rpOpenListingsSvc',
    function ($scope, rpOpenListingsSvc) {
        $scope.updating = false;

        if (typeof(EventSource) !== "undefined") {
            // Yes! Server-sent events support!
            var source = new EventSource('/listings/events');

            source.onmessage = function (event) {
                $scope.openListingsReport = event.data;
                $scope.$apply();
                console.log($scope.openListingsReport);
            };
        }
    } else {
        // Sorry! No server-sent events support..
        alert('SSE not supported by browser.');
    }

    $scope.update = function () {
        $scope.updateTime = Date.now();
        $scope.updating = true;
        rpOpenListingsSvc.update();
    }

    $scope.reset = function () {
        $scope.updating = false; …
Run Code Online (Sandbox Code Playgroud)

javascript server-sent-events angularjs

13
推荐指数
1
解决办法
1万
查看次数

服务器发送的事件:如何以跨浏览器的方式自动重新连接?

我实现了一些代码来查询数据库中的任何更改并发送事件. 这是我的PHP脚本的代码

header("Content-Type: text/event-stream");
header('Cache-Control: no-cache');

//****Some code here to query the database

echo "event: message\n";
echo "data: change_from_database \n";
echo "\n\n";
ob_flush();
flush();
Run Code Online (Sandbox Code Playgroud)

我依靠浏览器每次连接关闭时自动重新连接,所以我没有在我的服务器代码上实现任何循环.另外,我从这个线程中了解到,实现无限循环有许多缺点.

所以一切都在客户端工作正常:每次连接关闭时浏览器都会重新连接,每次服务器发送一个事件时都会触发事件; 除了没有重新连接的Firefox(40.0.2)之外.我知道它不是因为我写了一些JavaScript错误检查代码来测试这个:

var evtSource = new EventSource("../sse.php");
evtSource.onerror = function(event){
    var txt;
    switch( event.target.readyState ){
    case EventSource.CONNECTING:
        txt = 'Reconnecting...';
        break;
    }
    console.log(txt);
}
Run Code Online (Sandbox Code Playgroud)

因此,像每一秒后,铬控制台上的控制台例如日志"Reconnecting".另一方面,Firefox重新连接一次,再也不会重新连接.

如何编写代码以使其在Firefox上运行,也许还有其他支持服务器发送事件但不自动重新连接的浏览器?

javascript php firefox server-sent-events

13
推荐指数
1
解决办法
3359
查看次数

使用HTTP/2时,我们是否应该优先选择SSE + REST而不是websocket?

使用websocket时,我们需要一个专用的双向通信连接.如果我们使用http/2,我们有服务器维护的第二个连接.

在这种情况下,使用websocket似乎会引入不必要的开销,因为使用SSE和常规http请求,我们可以通过单个HTTP/2连接获得双向通信的优势.

你怎么看?

websocket server-sent-events http2

13
推荐指数
1
解决办法
5791
查看次数

JMeter与服务器发送事件的并行请求

我有一个JMeter测试,我正在使用循环来查明某些条件是否属实.我想(并且可以)在发送服务器发送事件(SSE)的资源上使用请求,而不是轮询.它应该工作的方式是,SSE线程被启动,而另一个线程被启动,它执行最终将导致发送特定事件的请求.如果收到该事件,则应继续处理.

也许图形化更清晰.我当前的脚本看起来像这样:

ThreadGroup
 |
 + request 1
 + request 2
 ...
 + request N
 + Transaction controller
 |  |
 |  + While controller
 |     + polling request
 |
 + request N+1
Run Code Online (Sandbox Code Playgroud)

我想要这样的东西

ThreadGroup
 | 
 + request 1
 + request 2
 ...
 + <help needed here>
 |  |
 |  + event thread
 |  |   + request SSE
 |  |       + onEvent x: y = true
 |  + action thread
 |     + request N
 |     + While y=false wait
 + request N+1 …
Run Code Online (Sandbox Code Playgroud)

java jmeter server-sent-events

13
推荐指数
1
解决办法
1070
查看次数