新聞中心
本篇文章為大家展示了如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理 ,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
成都創(chuàng)新互聯(lián)公司專注于企業(yè)成都營銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、武侯網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5技術(shù)、購物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為武侯等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
之前在網(wǎng)上翻了半天,也沒有找到關(guān)于如何 通過 laravel-echo
主動發(fā)送消息和 在 laravel-websockets
中自定義控制器的文章或教程。無奈之下只能翻 laravel-echo
和 laravel-websockets
的源碼了,小有收獲。在此為有需要的朋友指個方向,少踩一個坑。
在使用 laravel-echo
時,網(wǎng)頁想主動向服務(wù)器發(fā)送消息該怎么做呢?首先,最簡單的就是 Ajax
異步請求了,寫起來很容易。還有一種方式就是通過 websocket
了,既然已經(jīng)建立了 socket 連接,我們何不利用他來進(jìn)行雙向通信呢!
如何使用 laravel-echo
通過 websocket
進(jìn)行反向通信(這里的「反向」指從網(wǎng)頁向服務(wù)器發(fā)送消息)。
簡述
網(wǎng)頁默認(rèn)連接的 websocket 地址是 http://
。url 中的 /app/
部分是 pusher
中規(guī)定的,目前還無法修改。Echo
時的參數(shù)「key」,同時也是.env
文件中的 PUSHER_APP_KEY
環(huán)境變量。服務(wù)器端控制器是 laravel-websockets
已經(jīng)定義好的控制器:BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler
。現(xiàn)在我們要實現(xiàn)自己的控制器,來做在線狀態(tài)管理,所以就需要改變網(wǎng)頁默認(rèn)連接的 websocket 地址和后臺控制器。
修改前端監(jiān)聽地址
打開 resources/views/hellow.blade.php
視圖文件,在初始化 Echo
中的參數(shù)部分加入 wsPath
變量。此時 websocket 監(jiān)聽的地址就會變?yōu)?http://
。
window.Echo = new Echo({broadcaster: 'pusher',key: 'joker',// 在 socket 鏈接中設(shè)置 url 路徑wsPath: '/liam/hao',wsHost: location.hostname,wsPort: 2020,forceTLS: false,});
注意:
wsPath
變量一定要用 “/” 開頭,否則會報錯的
技巧:這里再提一個小知識點吧,
pusher
默認(rèn)會在連接 websocket 時發(fā)送http://sockjs.pusher.com/pusher
請求,如果看著別扭(我不喜歡在網(wǎng)站中出現(xiàn)自己控制范圍外的事情),可以在初始化Echo
的參數(shù)中加一個enabledTransports
變量,值是['ws', 'wss']
。這樣pusher
就會將http://sockjs.pusher.com/pusher
請求替換為你自己的 websocket 連接地址:window.Echo = new Echo({..// 加上這個參數(shù)后,就不會再向 http://sockjs.pusher.com/pusher 發(fā)送請求了enabledTransports: ['ws', 'wss'],});
后端添加新的路由
因為前端改變了監(jiān)聽地址。對應(yīng)的后端,也需要新增一個對應(yīng)的路由。我們打開 routes/web.php
文件,加入以下新路由:
Route::get('/login', function () {return view('login');});// 這個是 laravel-websockets 提供的門面方法,用來注冊自定義的 websocekt 路由// WebSocketsRouter 綁定的實際對象是 BeyondCode\LaravelWebSockets\Server\Router 有興趣的可以瞅瞅\BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter::webSocket('/liam/hao/app/{appKey}', \App\Http\Controllers\MyWebsocketHandler::class);
創(chuàng)建自定義控制器
上面的路由中綁定了一個 App\Http\Controllers\MyWebsocketHandler
類,現(xiàn)在我們就來實現(xiàn)這個類:
> php artisan make:controller MyWebsocketHandler Controller created successfully.
執(zhí)行上面的命令后,我們會在 app/Http/Controllers
文件夾中找到 MyWebsocketHandler.php
文件,我們來進(jìn)行一些修改:
getPayload()));$message = PusherMessageFactory::createForMessage($message, $connection, $this->channelManager);$message->respond();}public function onClose(ConnectionInterface $connection){$this->channelManager->removeFromAllChannels($connection);var_dump('close');}}
好了,我們現(xiàn)在來小測一下,看看新的路由有沒有生效。重啟 laravel-websockets
的 http 服務(wù)。打開瀏覽器的開發(fā)者工具,然后刷新頁面。如果像下圖一樣,在命令行終端里看到了我們 var_dump()
的數(shù)據(jù),那就說明新的路由和控制器已經(jīng)連通了:
注意:MyWebsocketHandler 并不是一般的 Controller,他需要繼承自
BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler
。如果你需要控制更多邏輯,可直接實現(xiàn)Ratchet\WebSocket\MessageComponentInterface
接口,并自己實現(xiàn)onOpen()
、onClose()
、onMessage()
等方法。
前端發(fā)送消息(重點)
重點來了哈,雖說是重點,但代碼很簡單:
Echo.channel('abcdefg.'+uuid).listen('LoginedEvent', (e) => {console.log(e);var session_id = e.session_id;location.href = location.origin+'/hello?session_id='+session_id;});// 我們在這里放置一個定時器,每三秒鐘向服務(wù)器發(fā)送一條數(shù)據(jù)setInterval(function(){// 這里新增一個向服務(wù)端發(fā)送消息的方法// 第一個參數(shù)是事件名,這個可以隨意寫,不需要與 Laravel 中做對應(yīng)// 第二個參數(shù)是具體數(shù)據(jù),這個就更隨意了Echo.connector.pusher.send_event('hi_girl', {my_name: 'LiamHao',my_height: 180,});}, 3000);
是不是很簡單,我們再來小測一下,看看服務(wù)端接收到的數(shù)據(jù)是什么樣子的:
后端已經(jīng)接收到數(shù)據(jù)了。做到這里,想必有些基礎(chǔ)的朋友應(yīng)該已經(jīng)可以做自己想做的事情了。
設(shè)置在線狀態(tài)
這里我們就不做太復(fù)雜了數(shù)據(jù)庫操作了,還是老樣子,以最簡單的方式,用 緩存做記錄吧。我們在 App\Http\Controllers\MyWebsocketHandler
的 onMessage()
和 onClose()
方法中分別加入記錄狀態(tài)的代碼:
public function onMessage(ConnectionInterface $connection, MessageInterface $message){var_dump(json_decode($message->getPayload()));// 每當(dāng)收到消息時,設(shè)置當(dāng)前連接狀態(tài)為“在線”,60 秒后過期\Cache::put('socekt-status', ['socket_id' => $connection->socketId,'status' => '在線',], 60);$message = PusherMessageFactory::createForMessage($message, $connection, $this->channelManager);$message->respond();}public function onClose(ConnectionInterface $connection){$this->channelManager->removeFromAllChannels($connection);var_dump('close');// 瀏覽器主動斷開連接時,設(shè)置當(dāng)前連接狀態(tài)為“離線”,不設(shè)置過期時間\Cache::put('socekt-status', ['socket_id' => $connection->socketId,'status' => '離線',]);}
然后修改下 resources/views/login.blade.php
視圖文件,在頁面中顯示連接的狀態(tài):
Websocket 連接列表
{{ var_export(\Cache::get('socekt-status')) }}
大功告成,我們來看下效果。先打開 http://
頁面,此時未顯示任何內(nèi)容。這是正常的,因為 Cache
中還沒有記錄任何信息。接下來再打開 http://
頁面,看下瀏覽器開發(fā)者工具中 websocket 已連接成功。下面見證奇跡的時刻到了,我們再將 http://
頁面刷新一次,此時會看到 Cache
中記錄的在線狀態(tài)信息:
我們再來試下斷開 websocekt 連接時,是否會顯示離線。將 http://
頁面直接關(guān)閉,也就是點標(biāo)簽頁上的「叉子」。再刷新下 http://
頁面:
上述內(nèi)容就是如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理 ,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當(dāng)前題目:如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理
文章路徑:http://www.ef60e0e.cn/article/iijsph.html