基於 go-Laravel-broadcast 實現 Laravel 的即時通訊(Broadcasting)

小滕發表於2019-04-18

最近,小滕基於Go寫了 laravel-echo-server 的Go語言版本,開源倉庫地址:https://github.com/Qsnh/go-laravel-broadca... ,感興趣的小夥伴可以去看下。

下面是是 go-laravel-broadcast 的使用教程:

環境

  • Laravel5.8
  • Redis

Step

首先,修改 EventServiceProvider 檔案,在 $listen 新增:

'App\\Events\\TestPrivateBroadcastEvent' => [
    'App\\Listeners\\TestPrivateBroadcastListener',
],

然後執行:

php artisan event:generate

緊接著,修改 TestPrivateBroadcastEvent 內容如下:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class TestPrivateBroadcastEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function broadcastOn()
    {
        return new PrivateChannel('App.User.1');
    }
}

注意這裡的頻道名,我們定義的是 App.User.1 ,其真是的頻道名是 private-App.User.1 。這個後面我們需要用得到。

之後,我們在命令列執行:

php artisan queue:work

啟動佇列處理程式。接下來,執行下面命令:

➜  laravel5.8 php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.22 — cli) by Justin Hileman
>>> event(new \App\Events\TestPrivateBroadcastEvent());
=> [
     null,
   ]
>>>

然後我們在 redis 的服務可以看到:

➜  ~ docker exec -it redis1 sh
# redis-cli
127.0.0.1:6379> psubscribe *
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "*"
3) (integer) 1
1) "pmessage"
2) "*"
3) "private-App.User.1"
4) "{\"event\":\"App\\\\Events\\\\TestPrivateBroadcastEvent\",\"data\":{\"socket\":null},\"socket\":null}"

沒有問題,已經成功的進行了廣播。接下來我們啟動下 go-laravel-broadcast 服務:

➜  laravel-broadcasting git:(master) ✗ ./client
INFO[0000] 0.0.0.0:8890/ws
INFO[0000] redis subscribe                               channel="private-App.User.*"

我們還需要修改前端的內容,這裡我們就在 welcome.blade.php 這個檔案修改,內容如下:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel</title>
    </head>
    <body>

    <script type="text/javascript">
               var ws = new WebSocket("ws://127.0.0.1:8890/ws?channel=private-App.User.1");

               ws.onopen = function()
               {
                  console.log("連線成功");
               };

               ws.onmessage = function (evt)
               {
                  var received_msg = evt.data;
                  console.log(evt.data);
               };

               ws.onclose = function()
               {
                  console.log("連線已關閉...");
               };
    </script>

    </body>
</html>

我們在 welcome.blade.php 建立了一個 websocket 客戶端,連線到了 ws://127.0.0.1:8890/ws?channel=private-App.User.1 這個地址,其中的
channel 的值就是我們前面 event 註冊的頻道名。我們先啟動一個服務:

php artisan serve

然後訪問 http://127.0.0.1:8000/,開啟控制檯,可以看到:

連線成功
(index):26 連線已關閉...

ws 連線被伺服器主動關閉,為什麼?因為 private 的 channel 需要驗證使用者的,所以我們需要先登入下,到 http://127.0.0.1:8000/login 登入下,在訪問首頁:

連線成功
3(index):21 hb

可以看到連線成功,沒有被關閉,且受到了 hb 的文字訊息,這個什麼?這是 go-laravel-server 的心跳訊息哦。

接下來,我們在執行下下面的命令:

➜  laravel5.8 php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.22 — cli) by Justin Hileman
>>> event(new \App\Events\TestPrivateBroadcastEvent());
=> [
     null,
   ]
>>>

在瀏覽器的控制檯上,我們可以看到:

連線成功
19(index):21 hb
(index):21 {"event":"App\\Events\\TestPrivateBroadcastEvent","data":{"socket":null},"socket":null}
2(index):21 hb

收到了 TestPrivateBroadcastEvent 的訊息了,這樣的話,我們就利用 go-laravel-broadcast 實現了實時通訊啦。


原文地址:小滕php部落格

相關文章