当前位置: 首页 > 工具软件 > PHP SSE > 使用案例 >

php服务器向客户端推送消息,PHP + SSE服务器向客户端推送消息

段超
2023-12-01

SSE与WebSocket作用相似,都是建立浏览器与服务器之间的通信渠道,然后服务器向浏览器推送信息。但是WebSocket比SSE强大很多,SSE只能作为一个轻量级的消息推送方案,解决了从服务端向客户端单向推送消息的场景,而Websocket是全双工通道,可以双向通信.SSE应用场景可以是微博更新,股价更新,消息通知,赛事结果等。

目前主流浏览器都支持SSE,但是IE系除外。

客户端代码

先来看客户端代码,新建一个HTML页面文件,在脚本部分添加以下代码:

if(typeof(EventSource) !== "undefined") {

let source = new EventSource("sse.php");

source.onmessage = (e) => {

if (e.data == 'null') {

return false;

} else {

let edata = JSON.parse(e.data);

$('#result').append(edata.id + ':' + edata.message + "
");

}

};

} else {

alert('您的浏览器不支持SSE');

}

首先,使用typeof(EventSource)来判断浏览器对SSE的支持情况。

接着创建一个新的EventSource对象,然后定义发送更新的服务端的URL(本例中是“sse.php”),如果是跨域的请求,需要这样设置:let source = new EventSource("http://xxx.com/sse.php", { withCredentials: true });,并需要服务端代码开启允许跨域。

每接收到一次更新,就会发生onmessage事件。

当onmessage事件发生时,把已接收的数据推入id为#result的元素中。

EventSource对象支持3种事件:

onopen:当通往服务器的连接被打开时触发。

onmessage:当接收到消息时触发。

onerror:当发生错误时触发。

出于安全,可以我们在onmessage事件中检测消息的来源域:

source.onmessage = (e) => {

if (e.origin != 'https://www.helloweba.net') {

alert('消息来源不属于https://www.helloweba.net');

return;

}

...

}

服务端代码

我们使用PHP来写一个服务端发送数据的例子,当然你也可以使用的Java / Python的等任意服务端语言实现。

服务器端事件流的语法是非常简单的。把“Content-Type”报头设置为“text / event-stream”。现在,就可以开始发送事件流了。

header('X-Accel-Buffering: no');

header('Content-Type: text/event-stream');

header('Cache-Control: no-cache');

ob_end_clean();

ob_implicit_flush(1);

while(1){

$data = [

"id" => time(),

"message" => '欢迎来到helloweba,现在是北京时间'.date('Y-m-d H:i:s')

];

returnEventData($data);

sleep(10);

}

function returnEventData($returnData, $event='message', $id=0, $retry=0){

$str = '';

if($id>0){

$str .= "id: {$id}".PHP_EOL;

}

if($event){

$str.= "event: {$event}".PHP_EOL;

}

if($retry>0){

$str .= "retry: {$retry}".PHP_EOL;

}

if(is_array($returnData)){

$returnData = json_encode($returnData);

}

$str .= "data: {$returnData}".PHP_EOL;

$str .= PHP_EOL;

echo $str;

}

以上代码流程大致为:

1.作者:把头"Content-Type"设置为"text/event-stream";

2.规定不对页面进行缓存;

3.输出发送数据;

4.向客户端刷新输出数据。

注意:每一次发送的信息,若干由个message组成,每个消息内部由若干行组成,每一行都是如下格式。

[field]: value\n

其中[field]有四个值,分别是:

id:数据标识符用ID字段表示,相当于每一条数据的编号。

event:表示自定义的事件类型,的英文默认message事件浏览器可以用。addEventListener()监听该事件。

retry:指定浏览器重新发起连接的时间间隔当时间间隔到期会重连,另外一个是由于网络错误等原因,导致连接出错时也会重连。

data:数据内容,如果数据很长,可以分成多行,一行求最后用\n\n结尾,行都前面用\n结尾。

完整的消息内容格式:

id: msg1\n

event: foo\n

retry: 10000\n

data: some text\n

data: another message\n

data: with two lines \n\n

上述代码中,我们设置了每隔10秒钟向客户端输出一条数据,实际应用中服务端有个任务当发现新的数据时就触发输出流事件。

原文链接:https://www.helloweba.net/javascript/606.html

 类似资料: