摘要:即時交互的應用在現(xiàn)代的應用中很多場景都需要運用到即時通訊,比如說最常見的支付回調(diào),與三方登錄。在生成事件時,已經(jīng)自動添加了該命名空間,該契約只約束方法。會將事件中的允許公開訪問的數(shù)據(jù)通過給定的頻道發(fā)布出去。
即時交互的應用
在現(xiàn)代的 Web 應用中很多場景都需要運用到即時通訊,比如說最常見的支付回調(diào),與三方登錄。這些業(yè)務場景都基本需要遵循以下流程:
客戶端觸發(fā)相關(guān)業(yè)務,并產(chǎn)生第三方應用的操作(比如支付)
客戶端等待服務端響應結(jié)果(用戶完成第三方應用的操作)
第三方應用通知服務端處理結(jié)果(支付完成)
服務端通知客戶端處理結(jié)果
客戶端依據(jù)結(jié)果做出反饋 (跳轉(zhuǎn)到支付成功頁面)
在過去,為了實現(xiàn)這種即時通訊,能讓客戶端正確響應處理結(jié)果,最為常用的技術(shù)就是輪詢,因為 HTTP 協(xié)議的單向性,客戶端只能一遍一遍的主動詢問服務端的處理結(jié)果。這種方式有顯見的缺陷,占用服務端資源不說,還不能實時獲得服務端處理結(jié)果。
現(xiàn)在,我們可以使用 WebSocket 協(xié)議來處理實時交互,它是一種雙向協(xié)議,允許服務端主動推送信息到客戶端。本篇我們將借助 Laravel 強大的事件系統(tǒng)來構(gòu)建實時的交互。你將需要用到以下知識:
Laravel Event
Redis
Socket.io
Node.js
Redis在開始之前,我們需要開啟一個 redis 服務,并在 Laravel 應用中進行配置啟用,因為在整個流程中,我們需要借助 redis 的訂閱和發(fā)布機制來實現(xiàn)即時通訊。
Redis 是一個開源高效的鍵值對存儲系統(tǒng)。它通常作為一個數(shù)據(jù)結(jié)構(gòu)服務器來存儲鍵值對,它可以支持字符串,散列,列表,集合和有序結(jié)合。在 Laravel 中使用 Redis 你需用通過 Composer 來安裝 predis/predis 包文件。
配置Redis 在應用中的配置文件存儲在 config/database.php,在這個文件中,你可以看到一個包含了 Redis 服務信息的 redis 數(shù)組:
"redis" => [ "cluster" => false, "default" => [ "host" => "127.0.0.1", "port" => 6379, "database" => 0, ], ]
如果你修改了 redis 服務的端口,請保持配置文件中的端口一致。
Laravel Event這里我們需要借助 Laravel 強大的事件廣播能力:
配置廣播事件
很多現(xiàn)代化的應用中,會使用 Web Sockets 來實現(xiàn)實時交互的用戶接口。當一些數(shù)據(jù)在服務端變更時,一條消息會通過 WebSocket 連接來傳遞到客戶端進行處理。
為了幫助你構(gòu)建這種類型的應用。Laravel 使通過 WebSocket 連接進行廣播事件變的非常簡單。Laravel 允許你廣播事件來共享事件的名稱到你的服務端和客戶端的 JavaScript 框架。
所有的事件廣播配置選項都被存儲在 config/broadcasting.php 配置文件中。Laravel 附帶了幾種可用的驅(qū)動如 Pusher,Redis,和 Log,我們將使用 Redis 作為廣播驅(qū)動,這里需要依賴 predis/predis 類庫。
由于默認的廣播驅(qū)動使用的是 pusher,所以我們需要在 .env 文件中設(shè)置 BROADCAST_DRIVER=redis。
我們創(chuàng)建一個 WechatLoginedEvent 事件類用來在用戶掃描微信登錄后進行廣播:
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 方法應返回一個數(shù)組,它表示所需廣播的頻道,而 broadcastAs 返回的是一個字符串,它表示廣播所觸發(fā)的事件,Laravel 默認的是返回事件類的全類名,這里是 AppEventsWechatLoginedEvent.
最重要的是你需要手動的讓該類實現(xiàn) ShouldBroadcast 契約。Laravel 在生成事件時,已經(jīng)自動添加了該命名空間,該契約只約束 broadcastOn 方法。
事件完成接下來就是觸發(fā)事件了,簡單的一行代碼就可以:
event(new WechatLoginedEvent($token, $channel));
這個操作會自動的觸發(fā)事件的執(zhí)行并將信息廣播出去。該廣播操作底層借助了 redis 的訂閱和發(fā)布機制。RedisBroadcaster 會將事件中的允許公開訪問的數(shù)據(jù)通過給定的頻道發(fā)布出去。如果你想對公開的數(shù)據(jù)擁有更多的控制,你可以在事件中添加 broadcastWith 方法,它應該返回一個數(shù)組:
/** * Get the data to broadcast. * * @return array */ public function broadcastWith() { return ["user" => $this->user->id]; }Node.js 和 Socket.io
對于發(fā)布出去的信息,我們需要一個服務來對接,讓其能對 redis 的發(fā)布能夠進行訂閱,并且能把信息以 WebSocket 協(xié)議轉(zhuǎn)發(fā)出去,這里我們可以借用 Node.js 和 socket.io 來非常方便的構(gòu)建這個服務:
// server.js var 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 服務端并監(jiān)聽 6001 端口,借用 redis 的 psubscribe 指令使用通配符來快速的批量訂閱,接著在消息觸發(fā)時將消息通過 WebSocket 轉(zhuǎn)發(fā)出去。
Socket.io 客戶端在 web 前端,我們需要引入 Socket.io 客戶端開啟與服務端 6001 端口的通訊,并訂閱頻道事件:
// client.js let 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è)置需要進行廣播的頻道及事件名稱
將廣播設(shè)置為使用 redis 驅(qū)動
提供一個持續(xù)的服務用于訂閱 redis 的發(fā)布,及將發(fā)布內(nèi)容通過 WebSocket 協(xié)議推送到客戶端
客戶端打開服務端 WebSocket 隧道,并對事件進行訂閱,根據(jù)指定事件的推送進行響應。
PS: 歡迎關(guān)注簡書 Laravel 專題,也歡迎 Laravel 相關(guān)文章的投稿 :),作者知識技能水平有限,如果你有更好的設(shè)計方案歡迎討論交流,如果有錯誤的地方也請批評指正,在此表示感謝 :)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/21861.html
摘要:打造你的即時應用二消息推送與監(jiān)聽年月日接于上篇博客打造你的即時應用一項目初始化構(gòu)建在上一篇博客中介紹了項目的基本構(gòu)建現(xiàn)在進入實戰(zhàn)操作一消息推送創(chuàng)建事件類的廣播推送通過來實現(xiàn)下面通過命令來創(chuàng)建一個事件類為了配合我們的廣播系統(tǒng)使用需要實現(xiàn)接 打造你的Laravel即時應用(二)-消息推送與監(jiān)聽 2019年08月04日20:16:21 XXM 接于上篇博客: 打造你的Laravel即時應用(...
摘要:配置項即時載入的服務提供者根目錄所有即時載入的服務注冊完成之后,會立即調(diào)用方法,并標記為已載入。最終就是將數(shù)組設(shè)置給的屬性將運用到所有的路由,再加載。 Laravel 配置項即時載入的服務提供者 (根目錄:/var/www/laravel/) 所有即時載入的服務注冊完成之后,會立即調(diào)用 register 方法,并標記為已載入。 隨后通過 IlluminateFoundationBoot...
摘要:在本文中,我們將了解中的懶加載和即時加載以及它如何在后臺運行。現(xiàn)在所有的房屋數(shù)據(jù)和在關(guān)系表中的數(shù)據(jù)都同時加載出來了,查詢的語句的是使用即時加載時僅執(zhí)行個查詢。總結(jié)現(xiàn)在你理解了這個過程,希望它能幫助你理解懶加載和即時加載的用法和基本原理。 Laravel中的Eloquent(ORM)的工作方式很令人驚訝,并提供訪問數(shù)據(jù)庫的非常簡單的方法。在本文中,我們將了解Laravel Eloquen...
摘要:今天,讓我們深入研究下的廣播系統(tǒng)。廣播系統(tǒng)的目的是用于實現(xiàn)當服務端完成某種特定功能后向客戶端推送消息的功能。這種使用場景可以完美詮釋廣播系統(tǒng)的工作原理。另外,本教程將使用廣播系統(tǒng)實現(xiàn)這樣一個即時通信應用。 這是一篇譯文,譯文首發(fā)于 Laravel 廣播系統(tǒng)工作原理,轉(zhuǎn)載請注明出處。 今天,讓我們深入研究下 Laravel 的廣播系統(tǒng)。廣播系統(tǒng)的目的是用于實現(xiàn)當服務端完成某種特定功能后向...
閱讀 1180·2021-11-24 09:39
閱讀 2688·2021-09-28 09:35
閱讀 1081·2019-08-30 15:55
閱讀 1371·2019-08-30 15:44
閱讀 885·2019-08-29 17:00
閱讀 1982·2019-08-29 12:19
閱讀 3319·2019-08-28 18:28
閱讀 697·2019-08-28 18:10