国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

Laravel構(gòu)建即時應(yīng)用的一種實(shí)現(xiàn)方法詳解

2024-05-04 23:59:55
字體:
供稿:網(wǎng)友

即時交互的應(yīng)用

大家應(yīng)該都有所體會,在現(xiàn)代的 Web 應(yīng)用中很多場景都需要運(yùn)用到即時通訊,比如說最常見的支付回調(diào),與三方登錄。這些業(yè)務(wù)場景都基本需要遵循以下流程:

  • 客戶端觸發(fā)相關(guān)業(yè)務(wù),并產(chǎn)生第三方應(yīng)用的操作(比如支付)
  • 客戶端等待服務(wù)端響應(yīng)結(jié)果(用戶完成第三方應(yīng)用的操作)
  • 第三方應(yīng)用通知服務(wù)端處理結(jié)果(支付完成)
  • 服務(wù)端通知客戶端處理結(jié)果
  • 客戶端依據(jù)結(jié)果做出反饋 (跳轉(zhuǎn)到支付成功頁面)

在過去,為了實(shí)現(xiàn)這種即時通訊,能讓客戶端正確響應(yīng)處理結(jié)果,最為常用的技術(shù)就是輪詢,因?yàn)?HTTP 協(xié)議的單向性,客戶端只能一遍一遍的主動詢問服務(wù)端的處理結(jié)果。這種方式有顯見的缺陷,占用服務(wù)端資源不說,還不能實(shí)時獲得服務(wù)端處理結(jié)果。

現(xiàn)在,我們可以使用 WebSocket 協(xié)議來處理實(shí)時交互,它是一種雙向協(xié)議,允許服務(wù)端主動推送信息到客戶端。本篇我們將借助 Laravel 強(qiáng)大的事件系統(tǒng)來構(gòu)建實(shí)時的交互。你將需要用到以下知識:

  • Laravel Event
  • Redis
  • Socket.io
  • Node.js

Redis

在開始之前,我們需要開啟一個 redis 服務(wù),并在 Laravel 應(yīng)用中進(jìn)行配置啟用,因?yàn)樵谡麄€流程中,我們需要借助 redis 的訂閱和發(fā)布機(jī)制來實(shí)現(xiàn)即時通訊。

Redis 是一個開源高效的鍵值對存儲系統(tǒng)。它通常作為一個數(shù)據(jù)結(jié)構(gòu)服務(wù)器來存儲鍵值對,它可以支持字符串,散列,列表,集合和有序結(jié)合。在 Laravel 中使用 Redis 你需用通過 Composer 來安裝 predis/predis 包文件。

配置

Redis 在應(yīng)用中的配置文件存儲在 config/database.php,在這個文件中,你可以看到一個包含了 Redis 服務(wù)信息的 redis 數(shù)組:

'redis' => [ 'cluster' => false, 'default' => [ 'host' => '127.0.0.1', 'port' => 6379, 'database' => 0, ],]

如果你修改了 redis 服務(wù)的端口,請保持配置文件中的端口一致。

Laravel Event

這里我們需要借助 Laravel 強(qiáng)大的事件廣播能力:

廣播事件

很多現(xiàn)代化的應(yīng)用中,會使用 Web Sockets 來實(shí)現(xiàn)實(shí)時交互的用戶接口。當(dāng)一些數(shù)據(jù)在服務(wù)端變更時,一條消息會通過 WebSocket 連接來傳遞到客戶端進(jìn)行處理。

為了幫助你構(gòu)建這種類型的應(yīng)用。Laravel 使通過 WebSocket 連接進(jìn)行廣播事件變的非常簡單。Laravel 允許你廣播事件來共享事件的名稱到你的服務(wù)端和客戶端的 JavaScript 框架。

配置

所有的事件廣播配置選項(xiàng)都被存儲在 config/broadcasting.php 配置文件中。Laravel 附帶了幾種可用的驅(qū)動如 Pusher,Redis,和 Log,我們將使用 Redis 作為廣播驅(qū)動,這里需要依賴 predis/predis 類庫。

由于默認(rèn)的廣播驅(qū)動使用的是 pusher,所以我們需要在 .env 文件中設(shè)置 BROADCAST_DRIVER=redis

我們創(chuàng)建一個 WechatLoginedEvent 事件類用來在用戶掃描微信登錄后進(jìn)行廣播:

<?phpnamespace App/Events;use App/Events/Event;use Illuminate/Queue/SerializesModels;use Illuminate/Contracts/Broadcasting/ShouldBroadcast;class WechatLoginedEvent extends Event implements ShouldBroadcast{ use SerializesModels; public $token; protected $channel; /**  * Create a new event instance.  *  * @param string $token  * @param string $channel  * @return void  */ public function __construct($token, $channel) {  $this->token = $token;  $this->channel = $channel; } /**  * Get the channels the event should be broadcast on.  *  * @return array  */ public function broadcastOn() {  return [$this->channel]; } /**  * Get the name the event should be broadcast on.  *  * @return string  */ public function broadcastAs() {  return 'wechat.login'; }}

其中你需要注意 broadcastOn 方法應(yīng)返回一個數(shù)組,它表示所需廣播的頻道,而 broadcastAs 返回的是一個字符串,它表示廣播所觸發(fā)的事件,Laravel 默認(rèn)的是返回事件類的全類名,這里是 App/Events/WechatLoginedEvent.

最重要的是你需要手動的讓該類實(shí)現(xiàn) ShouldBroadcast 契約。Laravel 在生成事件時,已經(jīng)自動添加了該命名空間,該契約只約束 broadcastOn 方法。

事件完成接下來就是觸發(fā)事件了,簡單的一行代碼就可以:

event(new WechatLoginedEvent($token, $channel));

這個操作會自動的觸發(fā)事件的執(zhí)行并將信息廣播出去。該廣播操作底層借助了 redis 的訂閱和發(fā)布機(jī)制。

RedisBroadcaster 會將事件中的允許公開訪問的數(shù)據(jù)通過給定的頻道發(fā)布出去。如果你想對公開的數(shù)據(jù)擁有更多的控制,你可以在事件中添加 broadcastWith 方法,它應(yīng)該返回一個數(shù)組:

/** * Get the data to broadcast. * * @return array */ public function broadcastWith()  { return ['user' => $this->user->id]; }

Node.js 和 Socket.io

對于發(fā)布出去的信息,我們需要一個服務(wù)來對接,讓其能對 redis 的發(fā)布能夠進(jìn)行訂閱,并且能把信息以 WebSocket 協(xié)議轉(zhuǎn)發(fā)出去,這里我們可以借用 Node.js 和 socket.io 來非常方便的構(gòu)建這個服務(wù):

// server.jsvar app = require('http').createServer(handler);var io = require('socket.io')(app);var Redis = require('ioredis');var redis = new Redis();app.listen(6001, function () { console.log('Server is running!') ;});function handler(req, res) { res.writeHead(200); res.end('');}io.on('connection', function (socket) { socket.on('message', function (message) { console.log(message) }) socket.on('disconnect', function () { console.log('user disconnect') })});redis.psubscribe('*', function (err, count) {});redis.on('pmessage', function (subscrbed, channel, message) { message = JSON.parse(message); io.emit(channel + ':' + message.event, message.data);});

這里我們使用 Node.js 引入 socket.io 服務(wù)端并監(jiān)聽 6001 端口,借用 redis 的 psubscribe 指令使用通配符來快速的批量訂閱,接著在消息觸發(fā)時將消息通過 WebSocket 轉(zhuǎn)發(fā)出去。

Socket.io 客戶端

在 web 前端,我們需要引入 Socket.io 客戶端開啟與服務(wù)端 6001 端口的通訊,并訂閱頻道事件:

// client.jslet io = require('socket.io-client')var socket = io(':6001')  socket.on($channel + ':wechat.login', (data) => {  socket.close()  // save user token and redirect to dashboard})

至此整個通訊閉環(huán)結(jié)束,開發(fā)流程看起來就是這樣的:

  • 在 Laravel 中構(gòu)建一個支持廣播通知的事件
  • 設(shè)置需要進(jìn)行廣播的頻道及事件名稱
  • 將廣播設(shè)置為使用 redis 驅(qū)動
  • 提供一個持續(xù)的服務(wù)用于訂閱 redis 的發(fā)布,及將發(fā)布內(nèi)容通過 WebSocket 協(xié)議推送到客戶端
  • 客戶端打開服務(wù)端 WebSocket 隧道,并對事件進(jìn)行訂閱,根據(jù)指定事件的推送進(jìn)行響應(yīng)。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網(wǎng)的支持。

 

注:相關(guān)教程知識閱讀請移步到PHP教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 获嘉县| 吉木萨尔县| 乌什县| 凤台县| 广安市| 谢通门县| 大厂| 黄浦区| 五台县| 福建省| 吉林省| 茌平县| 论坛| 靖宇县| 普陀区| 杂多县| 茶陵县| 邵阳县| 淮安市| 循化| 阳西县| 沂源县| 威宁| 上思县| 且末县| 双辽市| 农安县| 靖安县| 东港市| 金湖县| 武陟县| 上杭县| 仙游县| 镶黄旗| 赞皇县| 和平县| 宜兰县| 花莲县| 清水河县| 许昌县| 双牌县|