Javascript 如何使用HTML5 SSE发送json_编码数据

Javascript 如何使用HTML5 SSE发送json_编码数据,javascript,php,json,html,Javascript,Php,Json,Html,我有一个脚本,它触发一个SSE事件,用于从online.php获取json编码的数据。 在谷歌上,我通过引入换行符找到了使用sse发送JSON数据的方法 我想知道的是,当使用PHP的JSON_encode()函数创建JSON数组时,如何通过SSE发送JSON 我已经写了以下几行代码,但是有谁能帮我在哪里添加SSE所需的“数据:\n\n”吗 <script> if(typeof(EventSource)!=="undefined") { var source=new EventSo

我有一个脚本,它触发一个SSE事件,用于从online.php获取json编码的数据。 在谷歌上,我通过引入换行符找到了使用sse发送JSON数据的方法

我想知道的是,当使用PHP的JSON_encode()函数创建JSON数组时,如何通过SSE发送JSON

我已经写了以下几行代码,但是有谁能帮我在哪里添加SSE所需的“数据:\n\n”吗

<script>
if(typeof(EventSource)!=="undefined")
{
  var source=new EventSource("online.php");
  source.onmessage=function(event)
  {
     var data=JSON.parse(event.data);
     $("#new_message").html("Inbox"+data['total']);
  };    
}
else
{
  $("#new_message").html("HTML5 not supported");
}
</script>

if(typeof(EventSource)!=“未定义”)
{
var source=neweventsource(“online.php”);
source.onmessage=函数(事件)
{
var data=JSON.parse(event.data);
$(“#新消息”).html(“收件箱”+数据['total]);
};    
}
其他的
{
$(“#新#消息”).html(“不支持HTML5”);
}
online.php

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$data["total"]="hello";
echo json_encode($data);
ob_flush();
flush(); 
?>

您需要以EventStream格式发送它,在本例中,它只是在它前面加上
数据:

echo 'data: ' . json_encode($data) . "\n\n";

您可以像Ryan所说的那样对
$data
数组进行编码:

echo 'data: ' . json_encode($data) . "\n\n";
然后,客户端,
event.data
将被视为一个字符串,您可以使用查询的
jQuery.parseJSON()
轻松地将其解析为json。因此,您的客户端代码将如下所示:

// Check if the browser supports SSE
if (typeof (EventSource) !== "undefined") {

              var source = new EventSource("script.php");
              // Handle evetns
              source.onmessage = function(event) {
                  // parse the data that has an object as a string
                  var msg = $.parseJSON(event.data);
                     // Do awesome code with the values inside msg
              };
        } else {
              alert("Sorry, your browser doesn't support this awesome feature!");
        }

源:

您的脚本将只显示一次输出,因为它需要某种循环来保持运行(当然是有条件的,否则您将有数百万个实例运行!!)

我已经切碎了我今天早些时候编写的一个实现,它演示了这一点,还添加了一些额外的javascript/jquery来帮助更好地管理流。以下内容也适用于单线程PHP安装,如Xampp(用于本地开发) 关于Xampp的注意事项:由于PHP脚本处于循环中,并且不会立即终止,因此将停止新的PHP或agax脚本的运行。如果您还使用ajax调用PHP,则在beforesend中调用stream_close(),在success回调中调用stream_open()

下面的代码未经测试,但主要是从工作代码中获取的,所以应该可以

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

stream();

function stream(){
    $data = array();
    //collect data from database or wherever to stream to browser
    //example data
        $data[0]["name"] = 'Bob';
        $data[0]["total"] = rand(0,100);
        $data[0]["name"] = 'Jane';
        $data[0]["total"] = rand(0,100);

    //maybe there is no new data so just send one new line
    //this is required to check if the connection is still alive
    if(!empty($data)){  
        echo "\n";
    }else{              //Otherwise json encode the data for output
        echo 'data: '.json_encode($data)."\n\n";
    }
    flush();            //Flush the result to the browser
    sleep(1);           //Wait a second (or what ever you like)

    //If the browser is still connected
    if(!connection_aborted() && connection_status()==0){
        stream();       //recurse the function
    }
}

?>

<script>
    var webstream = false;

    function stream_open(){
        stream_close(); //Close the stream it (in case we got here weirdly)
        if(!!window.EventSource){   //Test compatibility
            webstream = new EventSource('./stream.php');
            console.log("Stream Opened");   //Log event for testing

            webstream.addEventListener('message', function(e){
                var data = JSON.parse(e.data);  //Parse the json into an object
                process_stream(data);
            },false);

            //Cleanup after navigating away (optional)              
            $(window).bind('beforeunload', function(){  
                webstream.onclose = function(){}; //delete onclose (optional)
                webstream.close();  //Close the stream
            });
        }
    }

    function stream_close(){
        if(typeof(webstream)=="object"){
            webstream.close();
            webstream = false;
            console.log("Stream Closed");   //Log event for testing
        }
    }

    function process_stream(data){
        //do something with the new data from the stream, e.g. log in console
        console.log(data);
    }


    //Optional:
    //Toggle stream on blur/focus
    //Good if the user opens multiple windows or Xampp?
        $(window).on("blur focus", function(e) {

            //get the last blur/focus event type
            var prevType = $(this).data("prevType") || null;

            if (prevType != e.type){
                console.log(e.type);    //Log event for testing (focus/blur)
                switch (e.type){
                    case "blur":
                        stream_close(); //Close stream on blur
                    break;
                    case "focus":
                        stream_open();  //Open stream on focus
                    break;
                }
            }

            //Store the last event type to data
            $(this).data("prevType", e.type);
        });

    // Optional:
    // Using idletimer plugin to close the stream in times of inactivity
    // https://github.com/thorst/jquery-idletimer/blob/master/src/idle-timer.js

        $(document).on("idle.idleTimer", function (){
            stream_close();
        });
        $(document).on("active.idleTimer", function (){
            stream_open();
        });
        $(document).idleTimer({timeout:5000}); //5 second idle timer
</script>

var-webstream=false;
函数流_open(){
stream_close();//关闭流(以防我们奇怪地到达这里)
if(!!window.EventSource){//测试兼容性
webstream=neweventsource('./stream.php');
console.log(“流已打开”);//用于测试的日志事件
webstream.addEventListener('message',函数(e){
var data=JSON.parse(e.data);//将JSON解析为一个对象
过程流(数据);
},假);
//导航离开后的清理(可选)
$(窗口).bind('beforeunload',function(){
webstream.onclose=function(){};//删除onclose(可选)
webstream.close();//关闭流
});
}
}
函数流_close(){
if(typeof(webstream)=“对象”){
webstream.close();
webstream=false;
console.log(“流关闭”);//用于测试的日志事件
}
}
函数进程流(数据){
//对流中的新数据执行一些操作,例如登录控制台
控制台日志(数据);
}
//可选:
//在模糊/聚焦上切换流
//如果用户打开多个窗口或Xampp是否良好?
$(窗口)。打开(“模糊焦点”,函数(e){
//获取最后一个模糊/聚焦事件类型
var prevType=$(this).data(“prevType”)| | null;
如果(prevType!=e.type){
console.log(e.type);//记录测试事件(焦点/模糊)
开关(e型){
案例“模糊”:
stream_close();//在模糊时关闭流
打破
案例“焦点”:
stream_open();//焦点时打开流
打破
}
}
//将最后一个事件类型存储到数据
$(this).data(“prevType”,e.type);
});
//可选:
//使用idletimer插件在不活动时关闭流
// https://github.com/thorst/jquery-idletimer/blob/master/src/idle-timer.js
$(document).on(“idle.idleTimer”,函数(){
流_close();
});
$(document).on(“active.idleTimer”,函数(){
流_open();
});
$(document.idleTimer({timeout:5000})//5秒怠速定时器

很抱歉,这在谷歌Chrome上运行良好,但在Mozilla Firefox上出现了问题。该函数在Mozilla中只执行一次,然后停止检索SSE。然而,谷歌浏览器中的一切似乎都很好。