[英]How to send json_encode data with HTML5 SSE
I have a script that fires an SSE event for fetching json encoded data from online.php. 我有一个脚本,它触发一个SSE事件,用于从online.php获取json编码数据。 On googling, I found ways to send JSON data with sse, by introducing line-breaks. 在谷歌搜索,我找到了通过引入换行符来发送带有sse的JSON数据的方法。
What I am looking for is how to send JSON over SSE when the JSON array is created using PHP's json_encode() function. 我正在寻找的是当使用PHP的json_encode()函数创建JSON数组时如何通过SSE发送JSON。
I have written the following lines of code, but could anybody help me with where to add the "data: \\n\\n" required for SSE? 我写了以下几行代码,但是有人可以帮助我在哪里添加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>
online.php 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格式发送它,在这种情况下,它只是在data:
前面加上它data:
echo 'data: ' . json_encode($data) . "\n\n";
You can encode the $data
array like Ryan said: 您可以对$data
数组进行编码,如Ryan所说:
echo 'data: ' . json_encode($data) . "\n\n";
Then, client side, event.data
will be viewed as a string, which you can then easily parse to json using query's jQuery.parseJSON()
. 然后,客户端, event.data
将被视为一个字符串,然后您可以使用查询的jQuery.parseJSON()
轻松解析为json。 so your client-side code will look something like this: 所以你的客户端代码看起来像这样:
// 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!");
}
Source: http://api.jquery.com/jquery.parsejson/ 资料来源: http : //api.jquery.com/jquery.parsejson/
Your script will only show output once as it needs to have some kind of a loop to keep running (conditionally of course or you'll have millions of instances running!!). 你的脚本只会显示一次输出,因为它需要有某种循环才能继续运行(当然有条件,或者你将有数百万个实例运行!!)。
I've chopped up an implementation I wrote earlier today which demonstrates this and also added some additional javascript/jquery to help manage the streams better. 我已经删除了我今天早些时候写的一个实现,它演示了这一点并添加了一些额外的javascript / jquery来帮助更好地管理流。 The below will also work on a single threaded PHP installation like Xampp (for local development) Notes on Xampp: As the PHP script is in a loop and doesn't terminate immediately it will stop a new php or agax script from running. 下面也适用于单线程PHP安装,如Xampp(用于本地开发)关于Xampp的注释:由于PHP脚本处于循环中并且不立即终止,因此它将停止运行新的php或agax脚本。 If you're using ajax as well to call PHP call stream_close() in the beforesend and stream_open() in the success callbacks. 如果您正在使用ajax在前端调用PHP调用stream_close()和在成功回调中调用stream_open()。
The below is untested but it's mainly grabbed from working code so it should be fine. 以下是未经测试但它主要是从工作代码中获取,所以应该没问题。
<?
//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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.