laravel9.x + beyondcode/laravel-websockets 实现广播 + websocket

beyondcode/laravel-websockets 文档

安装 beyondcode/laravel-websockets

composer  require  beyondcode/laravel-websockets
php  artisan  vendor:publish  --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider"  --tag="migrations"
php  artisan  migrate
php  artisan  vendor:publish  --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider"  --tag="config"

安装 pusher-php-server

composer  require  pusher/pusher-php-server

修改.env文件

BROADCAST_DRIVER=pusher
# 这里PUSHER_APP_ID、PUSHER_APP_KEY、PUSHER_APP_SECRET随便填写
PUSHER_APP_ID=test-websockets
PUSHER_APP_KEY=qwerty
PUSHER_APP_SECRET=123456789
PUSHER_HOST=localhost
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1

启动websockets

# 默认启动
php  artisan  websockets:serve
# 指定端口
php  artisan  websockets:serve  --port=3030
# 指定host
php  artisan  websockets:serve  --host=127.0.0.1

结合supervisord管理

安装客户端

npm install --save-dev laravel-echo pusher-js
npm run dev

修改 resources/js/bootstrap.js文件

// 打开注释
import Echo from  'laravel-echo';
import Pusher from  'pusher-js';
window.Pusher = Pusher;
window.Echo =  new  Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
wsHost: import.meta.env.VITE_PUSHER_HOST  ??  `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
wsPort: import.meta.env.VITE_PUSHER_PORT  ??  80,
wssPort: import.meta.env.VITE_PUSHER_PORT  ??  443,
    forceTLS: (import.meta.env.VITE_PUSHER_SCHEME  ??  'https') ===  'https',
    enabledTransports: ['ws', 'wss'],
});

增加一条web路由

Route::get('/', function () {
 return  view('welcome');
});
// 发送广播
Route::get('/event', function () {
$str =  \Illuminate\Support\Str::random();
 broadcast(new  \App\Events\Free($str));
});

welcome.blade.php文件新增

// 引入app.js文件
@vite('resources/js/app.js')
<script>
    // document.addEventListener 防止提示Echo未定义
    document.addEventListener("DOMContentLoaded", function (event) {
        Echo.channel(`channel-free`)
            .listen('Free', (e) => {
                console.log('listen ok')
                console.log(e.data);
            });
    })
</script>

Free Event 文件

<?php
namespace  App\Events;
use  Illuminate\Broadcasting\Channel;
use  Illuminate\Broadcasting\InteractsWithSockets;
use  Illuminate\Broadcasting\PresenceChannel;
use  Illuminate\Broadcasting\PrivateChannel;
use  Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use  Illuminate\Foundation\Events\Dispatchable;
use  Illuminate\Queue\SerializesModels;
class  Free  implements  ShouldBroadcast
{
 use  Dispatchable, InteractsWithSockets, SerializesModels;
 public $msg;

 public  function  __construct($msg)
 {

     $this->msg = $msg;

 }

 public  function  broadcastOn()
 {

     return  new  Channel('channel-free');

 }

 public  function  broadcastWith ()
 {

     return [
        'data'  =>  $this->msg
    ];
 }

}

自定义WebSocket处理程序

  1. 创建 MyCustomWebSocketHandler.php 文件

    <?php
    namespace  App;
    use  Illuminate\Support\Facades\Log;
    use  Ratchet\ConnectionInterface;
    use  Ratchet\RFC6455\Messaging\MessageInterface;
    use  Ratchet\WebSocket\MessageComponentInterface;
    class  MyCustomWebSocketHandler  implements  MessageComponentInterface
    {
      public  function  onOpen(ConnectionInterface $connection){
    
    // 这里处理 返回的Error Exception thrown undefined property Ratchet\Server\IoConnection::$app错误
    
         $socketId =  sprintf('%d.%d', random_int(1, 1000000000), random_int(1, 1000000000));
    
         $connection->socketId = $socketId;
    
         $connection->app =  new  \stdClass();
    
         $connection->app->id =  env('APP_NAME').'- Test';
    
          return $connection->send('您已链接:'.now()->toDateString());
    
     }
    
    public  function  onClose(ConnectionInterface $connection)
    {
    
    }
    
    public  function  onError(ConnectionInterface $connection, \Exception $e)
    {
    
    }
    
    public  function  onMessage(ConnectionInterface $connection, MessageInterface $msg)
    {
    
     // 接受客户端发送过来的信息
    
     Log::info($msg);
    
     return $connection->send($msg);
    }
    }
  2. 新增一条路由

    \BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter::webSocket('/my-websocket', \App\MyCustomWebSocketHandler::class);
  3. 客户端监听

    ws://127.0.0.1:6001/my-websocket

    beyondcode/laravel-websockets 自带了一个 Debug Dashboard

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

laravel9里面可以试试看soketi

不过soketi禁止大陆IP访问,需要特殊处理才能打开。

2周前 评论
会尿尿的大鲨鱼 (楼主) 2周前
91it (作者) 2周前

方便做集群部署吗

2周前 评论
会尿尿的大鲨鱼 (楼主) 2周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!