溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理

發(fā)布時間:2021-09-18 10:16:00 來源:億速云 閱讀:139 作者:柒染 欄目:編程語言

本篇文章為大家展示了如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理 ,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理

之前在網(wǎng)上翻了半天,也沒有找到關(guān)于如何 通過 laravel-echo 主動發(fā)送消息laravel-websockets 中自定義控制器 的文章或教程。無奈之下只能翻 laravel-echolaravel-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://<your.host>:<wsPort>/app/<key>。url 中的 /app/ 部分是 pusher 中規(guī)定的,目前還無法修改。<key> 指實例化 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://<your.host>:<wsPort><wsPath>/app/<key>。

        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)行一些修改:

<?phpnamespace App\Http\Controllers;use BeyondCode\LaravelWebSockets\WebSockets\Messages\PusherMessageFactory;use BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler;use Ratchet\ConnectionInterface;use Ratchet\RFC6455\Messaging\MessageInterface;// 注意這里要繼承自 WebSocketHandlerclass MyWebsocketHandler extends WebSocketHandler{public function onMessage(ConnectionInterface $connection, MessageInterface $message){var_dump(json_decode($message->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)連通了:

「手把手」利用laravel-echo主動向服務(wù)端發(fā)送消息,實現(xiàn)在線狀態(tài)管理

注意: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ù)是什么樣子的:

如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理

后端已經(jīng)接收到數(shù)據(jù)了。做到這里,想必有些基礎(chǔ)的朋友應(yīng)該已經(jīng)可以做自己想做的事情了。

設(shè)置在線狀態(tài)

這里我們就不做太復(fù)雜了數(shù)據(jù)庫操作了,還是老樣子,以最簡單的方式,用 緩存 做記錄吧。我們在 App\Http\Controllers\MyWebsocketHandleronMessage()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):

    <body><input type="text" name="username"><input type="text" name="password"><button>登陸</button><!-- 我們在這里簡單的展示一下連接的狀態(tài) --><h2>Websocket 連接列表</h2><!-- 用 blade 模板語法渲染數(shù)據(jù),簡單的打印下數(shù)據(jù) --><pre>{{ var_export(\Cache::get('socekt-status')) }}</pre></body>

大功告成,我們來看下效果。先打開 http://<your.host>/login 頁面,此時未顯示任何內(nèi)容。這是正常的,因為 Cache 中還沒有記錄任何信息。接下來再打開 http://<your.host>/hello 頁面,看下瀏覽器開發(fā)者工具中 websocket 已連接成功。下面見證奇跡的時刻到了,我們再將 http://<your.host>/login 頁面刷新一次,此時會看到 Cache 中記錄的在線狀態(tài)信息:

「手把手」利用laravel-echo主動向服務(wù)端發(fā)送消息,實現(xiàn)在線狀態(tài)管理

我們再來試下斷開 websocekt 連接時,是否會顯示離線。將 http://<your.host>/hello 頁面直接關(guān)閉,也就是點標(biāo)簽頁上的「叉子」。再刷新下 http://<your.host>/login 頁面:

如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理

上述內(nèi)容就是如何通過laravel-echo主動向服務(wù)端發(fā)送消息以及實現(xiàn)在線狀態(tài)管理 ,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI