首頁 web前端 html教學 使用php+swoole对client数据实时更新(二)_html/css_WEB-ITnose

使用php+swoole对client数据实时更新(二)_html/css_WEB-ITnose

Jun 21, 2016 am 09:00 AM

上一篇提到了swoole的基本使用,现在通过几行基本的语句来实现比较复杂的逻辑操作:

先说一下业务场景。我们目前的大多数应用都是以服务端+接口+客户端的方式去协调工作的,这样的好处在于不论是处在何种终端的情况下,都可以完美的和服务端兼容。这样就轻松实现了MVC各个部分的真正解耦。但是提高程序的友好性还是有很多路要走,其中一个大家都会遇到的就是数据实时更新的问题。比如一个用户在手机上做了添加操作,这时候其他的终端也应该及时显示数据的变化情况。这个对于手机来说还算好办,因为现在的各种推送服务完全可以满足需求,当收到推送更新时,根据推送内容请求相应接口就可以了。但是放到PC上就不是这么回事了。浏览器和http协议的特殊性质不得不让我们另辟蹊径。

举一个大家生活中都会遇到的场景:某个周末你想要和女朋友去看一场电影,你在自己的pc上找到了某场的场次和座位。正当你要下单支付时,系统提示该座位已经售出,这时你不得不重新回到选座页面重新挑选。那如果改进一下产品体验,当有别的用户已经购买某个座位的时候,浏览器会及时将座位标识已售出,这样你就不用来回操作,节省操作时间。

** 针对上述的情景呢,这里有一个系统间交互的流程图:**

  • 上面一行就是使用系统的当前用户,他对数据进行了相关操作,同时返回操作结果

下面一行是其他用户也正在操作同一条数据。当①(绿色)返回结果时,web服务器会同时告诉当前用户和redis队列服务(①黄色),因为websocket服务实时监听redis,这样一旦有数据变化,websocket服务会及时感知。此时通过与浏览器建立的长连接进行通讯并告知数据已经更新并重新加载。

另外一种方式是当①(绿色)返回结果时不告诉redis队列,而是直接通讯websocket服务数据已经发生变化,再由websocket服务通知浏览器客户端重新加载。因为此种方案比较简单再加上swoole对一些操作的封装比较便利,这里就采用此种办法

  • 当websocket连接被打开时,向socket服务发送当前注册id,因为只有这样websocket服务才能定向的为指定连接发送数据
ws.onopen = function(){    console.log("socket连接已打开");    $.post('/mercha/merchant/find',function(d){ //从web服务端获取注册id        d = $.parseJSON(d);        ws.send("merchantId_"+d.data.id);    })};
登入後複製
  • 当websocket服务收到注册id时会将当前连接的id和由服务端传来的商户id对应关系写入redis
$server->on('Message', function ($serv, $frame) {    if(stripos($frame->data,'merchantId_') !== false){        $fd = $redis->get($frame->data);        if($fd != null){            $fd = json_decode($fd,true);        }        //这里的$frame->fd是指当前的websocket连接id,swoole会通过此id发送给对应的接收方,可以理解为手机号码        $fd[$frame->fd] = $frame->fd;        $fd = json_encode($fd);        $redis->set($frame->data,$fd);    }});
登入後複製
  • 因为swoole_websocket_server 继承自 swoole_http_server ,这样就可以通过http的方式和websocket服务进行交互
$server->on('Request', function ($req, $respone) {    if(isset($req->get['merchantId'])){        global $server;        global $redis;        $merchantId = $req->get['merchantId'];        $fd = $redis->get("merchantId_".$merchantId);        if($fd != null){            $fd = json_decode($fd,true);        }        $err = 0;        if(is_array($fd)){            foreach($fd as $f){                $res = @$server->push($f, "refresh");                if($res === false){                    unset($fd[$f]);                    $err++;                }            }            if($err){                $fd = json_encode($fd);                $redis->set("merchantId_".$merchantId,$fd);            }        }    }    $respone->end("success");});
登入後複製

** 需要强调的一点是监听http请求的server并不具备push方法,所以这里通过全局变量的方式使用websocket的$server来向客户端发送数据 **

以上就是解决问题的大概思路了,文章最后会附上websocket的服务端源码,因为业务稍多所以里面集成了很多业务代码,而且需要运行起来必须要先安装swoole的扩展,安装方式上篇文章会有说明,所以这里仅供参考

对于图中另一种使用redis的方式也是很好的,之前采用了redis发布订阅的模式基本可以达到想要的效果。但是中间遇到一个问题redis的subscribe运行几十秒后,就会抛出一个RedisException。原因处在于,php的redis库使用的subscribe是使用PHP内置的socket,而php.ini默认是设置了socket的超时时间是60秒,所以大家只要找到default_socket_timeout 这个配置项,把时间改长点就可以了。或者在代码中加入ini_set('default_socket_timeout', -1);

websocket服务端源码

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

公眾號網頁更新緩存難題:如何避免版本更新後舊緩存影響用戶體驗? 公眾號網頁更新緩存難題:如何避免版本更新後舊緩存影響用戶體驗? Mar 04, 2025 pm 12:32 PM

公眾號網頁更新緩存難題:如何避免版本更新後舊緩存影響用戶體驗?

如何使用HTML5表單驗證屬性來驗證用戶輸入? 如何使用HTML5表單驗證屬性來驗證用戶輸入? Mar 17, 2025 pm 12:27 PM

如何使用HTML5表單驗證屬性來驗證用戶輸入?

如何高效地在網頁中為PNG圖片添加描邊效果? 如何高效地在網頁中為PNG圖片添加描邊效果? Mar 04, 2025 pm 02:39 PM

如何高效地在網頁中為PNG圖片添加描邊效果?

HTML5中跨瀏覽器兼容性的最佳實踐是什麼? HTML5中跨瀏覽器兼容性的最佳實踐是什麼? Mar 17, 2025 pm 12:20 PM

HTML5中跨瀏覽器兼容性的最佳實踐是什麼?

我如何使用html5< time> 元素以語義表示日期和時間? 我如何使用html5< time> 元素以語義表示日期和時間? Mar 12, 2025 pm 04:05 PM

我如何使用html5< time> 元素以語義表示日期和時間?

< datalist>的目的是什麼。 元素? < datalist>的目的是什麼。 元素? Mar 21, 2025 pm 12:33 PM

< datalist>的目的是什麼。 元素?

> gt;的目的是什麼 元素? > gt;的目的是什麼 元素? Mar 21, 2025 pm 12:34 PM

> gt;的目的是什麼 元素?

< meter>的目的是什麼。 元素? < meter>的目的是什麼。 元素? Mar 21, 2025 pm 12:35 PM

< meter>的目的是什麼。 元素?

See all articles