最新赞助活动温馨提示:自愿赞助服务器费用,学生和没有工作的整站资源免费下载!
头像

简单实用的PHP代码和SSE实现服务器向客户端推送消息

来源:http://www.erdangjiade.com/php/8740.html 沐浴春风 2019-04-01 14:48浏览(1212)

简单实用的PHP代码和SSE实现服务器向客户端推送消息,SSE(server-sent event)是基于HTML5的服务器推送消息事件,它允许服务端单向向浏览器客户端发送数据,SSE使用流信息向浏览器推送信息,浏览器自动接收服务端推送过来的消息,它是基于HTTP协议。

0、请不要问“在不在”之类的问题,有问题直接问!1、学生或暂时没有工作的童鞋,整站资源免费下载!2、¥9.9充值终身VIP会员,加我微信,826096331 拉你进VIP群学习!3、程序员加油,技术改变世界。 在线 充值

简单实用的PHP代码和SSE实现服务器向客户端推送消息
分类:PHP > 函数 难易:中级
查看演示 下载资源: 下载资源 下载积分: 30 积分

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

先来看客户端代码,新建一个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 + "<br/>"); 
        } 
    }; 
} 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.erdangjiade.comt') { 
    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组成,每个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秒钟向客户端输出一条数据,实际应用中服务端有个任务当发现新的数据时就触发输出流事件。
声明:本文为原创文章,如需转载,请注明来源erdangjiade.com并保留原文链接:https://www.erdangjiade.com/php/8740.html
评论3
头像

友情提示:垃圾评论一律封号 加我微信:826096331拉你进VIP群学习群

  • 头像 板凳
    10-21 10:10
    kkmllj2
    完全看不懂,哈哈。一直没有接触过
  • 头像 椅子
    03-01 14:32
    3078847178@qq.com
    来学习了
  • 头像 沙发
    06-20 13:31
    xfxfxf
    有源代码包吗
1 2