日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

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

發(fā)布時(shí)間:2025/3/20 php 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php 通知客户端,PHP+SSE服务器向客户端推送消息 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

SSE與WebSocket作用相似,都是建立瀏覽器與服務(wù)器之間的通信渠道,然后服務(wù)器向?yàn)g覽器推送信息。 但是WebSocket比SSE強(qiáng)大很多,SSE只能作為一個(gè)輕量級(jí)的消息推送方案,解決了從服務(wù)端向客戶端單向推送消息的場(chǎng)景,而Websocket是全雙工通道,可以雙向通信。 SSE應(yīng)用場(chǎng)景可以是微博更新、股價(jià)更新、消息通知、賽事結(jié)果等。

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

客戶端代碼

先來看客戶端代碼,新建一個(gè)html頁面文件,在script部分添加以下代碼:

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)來判斷瀏覽器對(duì)SSE的支持情況。

接著創(chuàng)建一個(gè)新的EventSource對(duì)象,然后定義發(fā)送更新的服務(wù)端的 URL(本例中是 "sse.php"),如果是跨域的請(qǐng)求,需要這樣設(shè)置:let source = new EventSource("http://xxx.com/sse.php", { withCredentials: true });,并需要服務(wù)端代碼開啟允許跨域。

每接收到一次更新,就會(huì)發(fā)生 onmessage 事件。

當(dāng) onmessage 事件發(fā)生時(shí),把已接收的數(shù)據(jù)推入 id 為 #result 的元素中。

EventSource 對(duì)象支持3種事件:

onopen:當(dāng)通往服務(wù)器的連接被打開時(shí)觸發(fā)。

onmessage:當(dāng)接收到消息時(shí)觸發(fā)。

onerror:當(dāng)發(fā)生錯(cuò)誤時(shí)觸發(fā)。

出于安全,我們可以在onmessage事件中檢測(cè)消息的來源域:

source.onmessage = (e) => {

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

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

return;

}

...

}

服務(wù)端代碼

我們使用PHP來寫一個(gè)服務(wù)端發(fā)送數(shù)據(jù)的例子,當(dāng)然你也可以使用Java/Python等任意服務(wù)端語言實(shí)現(xiàn)。

服務(wù)器端事件流的語法是非常簡(jiǎn)單的。把 "Content-Type" 報(bào)頭設(shè)置為 "text/event-stream"。現(xiàn)在,就可以開始發(fā)送事件流了。

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,現(xiàn)在是北京時(shí)間'.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.把報(bào)頭 "Content-Type" 設(shè)置為 "text/event-stream";

2.規(guī)定不對(duì)頁面進(jìn)行緩存;

3.輸出發(fā)送數(shù)據(jù);

4.向客戶端刷新輸出數(shù)據(jù)。

注意:每一次發(fā)送的信息,由若干個(gè)message組成,每個(gè)message內(nèi)部由若干行組成,每一行都是如下格式。

[field]: value\n

其中[field]有四個(gè)值,分別是:

id:數(shù)據(jù)標(biāo)識(shí)符用id字段表示,相當(dāng)于每一條數(shù)據(jù)的編號(hào)。

event:表示自定義的事件類型,默認(rèn)是message事件。瀏覽器可以用addEventListener()監(jiān)聽該事件。

retry:指定瀏覽器重新發(fā)起連接的時(shí)間間隔。當(dāng)時(shí)間間隔到期會(huì)重連,另外一個(gè)是由于網(wǎng)絡(luò)錯(cuò)誤等原因,導(dǎo)致連接出錯(cuò)時(shí)也會(huì)重連。

data:數(shù)據(jù)內(nèi)容,如果數(shù)據(jù)很長,可以分成多行,最后一行用\n\n結(jié)尾,前面行都用\n結(jié)尾。

完整的消息內(nèi)容格式:

id: msg1\n

event: foo\n

retry: 10000\n

data: some text\n

data: another message\n

data: with two lines \n\n

上述代碼中,我們?cè)O(shè)置了每隔10秒鐘向客戶端輸出一條數(shù)據(jù),實(shí)際應(yīng)用中服務(wù)端有個(gè)任務(wù)當(dāng)發(fā)現(xiàn)新的數(shù)據(jù)時(shí)就觸發(fā)輸出流事件。

總結(jié)

以上是生活随笔為你收集整理的php 通知客户端,PHP+SSE服务器向客户端推送消息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。