ホームページ PHPフレームワーク Laravel Laravelフレームワークの組み込みブロードキャスト機能がクライアントとのリアルタイム通信を実現する方法

Laravelフレームワークの組み込みブロードキャスト機能がクライアントとのリアルタイム通信を実現する方法

Jul 31, 2018 am 10:36 AM

Laravelフレームワークは多くの開発パッケージの機能を統合していますが、確かに優れたフレームワークです。次の記事では、 Laravel 5.6 バージョンに基づいて、組み込みのブロードキャスト関数を使用してクライアントとのリアルタイム通信を実現する方法を説明します。

1.準備する

ブロードキャストシステム

ユーザー認証

イベントシステム

キューシステム

フロントエンドガイド

tlaverdure/laravel-echo-server

はい、これが必要な知識の予備です。

PHP自体はWebSocketをサポートしていないため、「サーバー」データを「クライアント」に送信できる間接層が必要です。つまり、リアルタイム通信の実現は、

「Laravel」→「間接層」

「間接層」→「クライアント」

の2つのステップに分かれます。間接層にどのような実装を使用するかについては、後で説明します。

2. 設定

上記のブロードキャスト システムのドキュメントによると、最初に次の設定作業を行う必要があります。

(1) まず、config/broadcasting.php または .env ファイルを変更します。この機能をオンにしてデバッグを容易にするために、ブロードキャスト デフォルト ドライバーがログに記録されていることを確認してください。

(2) Broadcastを使用するには、相互依存しているLaravelのイベントシステムを理解する必要があります。次に「ブロードキャスト」できるイベントを作成します。

app/Providers/EventServiceProvider.php を変更し、メンバー変数 $listen を追加します。

'App\Events\OrderShipped' => [
    'App\Listeners\SendShipmentNotification',
],
ログイン後にコピー

ここでは、このイベントに OrderShipped (注文は決済されました) という名前を付けます。

イベントの実行 (つまり、クライアントへのブロードキャスト) を非同期に変更する必要がある場合は、上記のキュー システムのドキュメントを参照してください。

(3) イベントを「ブロードキャスト」できるようにするには、イベント クラスに ShouldBroadcast インターフェイスを継承させる必要があります。

app/Events/OrderShipped.php を開き、クラス定義を次のように変更します:

class OrderShipped implements ShouldBroadcast
ログイン後にコピー

(4) ShouldBroadcast インターフェイスには、このイベントがどの「チャネル」であるかをフレームワークに通知するために使用される、broadcastOn メソッドの実装が必要です。に送信された。

Laravel のブロードキャスト システムでは、複数のチャネルが存在することができます。ユーザー名を使用して異なるチャネルを区別できるため、異なるユーザーが異なるチャネルを使用して異なるメッセージを取得し、異なるクライアントと個別に通信できます。

もちろん、チャンネルに任意の名前を付けることもできますが、一定のルールを設けた方が良いでしょう。

Artisan コマンドによって生成されたイベント コードを使用しただけなので、ファイルの下部に broadcastOn メソッドの定義がすでに表示されています。これを少し変更します:

public function broadcastOn()
{
    return new Channel('orderStatus');
}
ログイン後にコピー

ここではチャネルに orderStatus という名前を付けて return します。つまり、このイベントがブロードキャストされると、orderStatus という名前のチャネルにブロードキャストされます。

これは「パブリックチャンネル」です。誰でもこのチャンネルを監視し、ブロードキャストメッセージを受信できます。 Laravel は「プライベート チャネル」も提供します。これは、権限の検証後にのみ正常に監視できます。それについては後で話します。

(5) デフォルトでは、Laravelはデータなしで「イベント名」をブロードキャストの「メッセージ名」として使用します。イベント クラス内にメンバー変数を追加し、クライアントにデータを送信するようにコンストラクターを変更できます。

//可添加任意成员变量
public $id;
//事件构造函数
public function __construct($id)
{
    $this->id = $id;
}
//自定义广播的消息名
public function broadcastAs()
{
    return 'anyName';
}
ログイン後にコピー

(6) 以上で、放送の基本的な仕組みはほぼ確立しました。次に、「イベントをトリガー」できる (つまり、ブロードキャストを送信できる) インターフェースが必要です。

routes/api.php に次のコードを追加します:

Route::get('/ship', function (Request $request)
{
    $id = $request->input('id');
    event(new OrderShipped($id)); // 触发事件
    return Response::make('Order Shipped!');
});
ログイン後にコピー

(7) 以上です。 Postman を開き、http://***/api/ship?id=1000 と入力して送信します。

storage/logs/laravel.log を開くと、さらにいくつかの行が見つかります:

[2018-03-02 01:41:19] local.INFO: Broadcasting [App\Events\OrderShipped] on channels [orderStatus] with payload:
{
    "id": "1000",
    "socket": null
}
ログイン後にコピー

おめでとうございます。ブロードキャスト ログ ドライバーが正常に構成されました。

3. ブロードキャスト

前のセクションでは、ブロードキャスト ドライバーとしてログを使用しました。これは、ブロードキャスト メッセージがログに記録されることを意味します。これには、冒頭で述べた「間接層」を使用する必要があります。

(1) まず、ドライバーをログからプッシャーに変更します。

Redis のインストール手順を節約するために、HTTP プロトコルを使用して、互換性のある「ローカル プッシャー サーバー」(つまり、間接層) に直接プッシュします。

(2) Laravel には組み込みの Broadcast Pusher Driver がないため、Composer を使用して Pusher PHP SDK をインストールする必要があります:

composer require pusher/pusher-php-server
ログイン後にコピー

(3) AppProvidersBroadcastServiceProvider を登録します。

Laravel 5.6 の場合、config/app.php のプロバイダー配列内の対応するコメントをコメント解除するだけで済みます。

(4) 次に、サーバーとクライアント間の通信のための「間接層」をインストールして構成する必要があります。

公式ドキュメントの推奨事項である tlaverdure/laravel-echo-server を使用します。 Node.js + Socket.IOを使用して実装されたWebSocketサーバーです。

Pusher HTTP API と互換性があるため、上記のように Redis の代わりに Driver を直接 Pusher に変更できます。

npm install -g laravel-echo-server
ログイン後にコピー

設定ファイルを初期化し、プロンプトに従って入力します。

laravel-echo-server init
ログイン後にコピー

laravel-echo-server.json を開いて、いくつかの主要な設定項目が正しいかどうかを確認してください:

"authHost": "http://xxx" // 确保能够访问到你的 Laravel 项目
"port": "6001" // 建议不作修改,这是与客户端通信的端口
"protocol": "http" // 与客户端通信的协议,支持 HTTPS
ログイン後にコピー

复制两个值:clients.appId 以及 clients.key,并修改 config/broadcasting.php。

'pusher' => [
    'driver' => 'pusher',
    'key' => env('PUSHER_APP_KEY'),
    'secret' => null,
    'app_id' => env('PUSHER_APP_ID'),
    'options' => [
        'host' => 'localhost',
        'port' => 6001,
    ],
],
ログイン後にコピー

顾名思义,将 appId 和 key 分别填入相应配置项或修改 .env 文件即可。

接下来,我们便可以使用命令 laravel-echo-server start 来启动服务器,监听来自 Laravel 的「广播」请求、以及来自客户端的「收听」请求,并转发相应广播消息。

(5)从这里开始我们将会配置前端部分。

首先,需要配置 CSRF Token。

如果你使用 Blade 模板引擎,则执行 php artisan make:auth 命令即可将 Token 加入 resources/views/layouts/app.blade.php。

若没有使用此模板文件,则可以直接在 Blade 模板文件首行直接写入 Meta 值。

为了便于测试,我们在 resources/views/welcome.blade.php 内添加:

<meta name="csrf-token" content="{{ csrf_token() }}">
ログイン後にコピー

对于前后端分离的项目,可关闭 CSRF Token 验证。

(6)其次,你需要引用 Socket.IO 的客户端 JS 文件,位置同上。

<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>
ログイン後にコピー

(7)这里我们采用官方的 Laravel Echo 扩展包收听服务端广播。打开 resources/assets/js/bootstrap.js,修改最后几行即可。

import Echo from 'laravel-echo'

window.Echo = new Echo({
    broadcaster: &#39;socket.io&#39;,
    host: window.location.hostname + &#39;:6001&#39;
});
ログイン後にコピー

接着编写「收听频道」代码,非常简单:

Echo.channel(`orderStatus`) // 广播频道名称
    .listen(&#39;OrderShipped&#39;, (e) => { // 消息名称
        console.log(e); // 收到消息进行的操作,参数 e 为所携带的数据
    });
ログイン後にコピー

(8)安装依赖,编译前端文件。执行如下命令:

npm install
npm run dev
ログイン後にコピー

最后,在 Blade 模板内引用我们刚刚写好的 JS 脚本。由于 app.js 默认已经引用 bootstrap.js,所以我们只需要引用 app.js 即可。

我们在第(5)步的文件内添加:

<script src="{{ asset(&#39;/js/app.js&#39;) }}"></script>
ログイン後にコピー

(9)好了!在查看效果前,不要忘记执行第(4)步的最后一条命令,启动 Laravel Echo Server。

Laravel 默认已经定义首页路由渲染 welcome.blade.php 模板,现在只要使用浏览器访问应用 URL 即可。

如果查看 Chrome 控制台,没有任何错误产生;查看命令行窗口,没有错误输出;则说明客户端与服务器似乎已经正常建立 WebSocket 连接。

这时,你可以重新打开Postman,发送上一节中的请求。

再次查看如上两个窗口,会有惊喜哟。

4、私有频道

上一节我们成功实现可以被任何人收听的「共有频道」广播,那么如何与部分客户端进行通讯呢?仅仅依靠前端的验证是不够的。我们需要创建带有「认证」功能的「私有频道」。

(1)首先,打开 app/Providers/BroadcastServiceProvider.php,在上一节中我们已经注册此服务提供者,现在我们需要取消注释一部分代码。

public function boot()
{
    Broadcast::routes(); // 还记得 laravel-echo-server.json 的 authEndpoint 配置项吗?
    require base_path(&#39;routes/channels.php&#39;);
}
ログイン後にコピー

Broadcast::routes() 用于注册验证路由(即 /broadcasting/auth),当客户端收听频道时,Laravel Echo Server 会访问此路由,以验证客户端是否符合「认证」条件。

(2)Broadcast 认证分为两个部分:

使用 Laravel 内置的 Auth 系统进行认证。

根据自定义规则进行部分频道的认证。

(3)首先,需要配置 Auth 认证系统。

根据情况修改 .env 文件的数据库配置项后,只需要执行 php artisan make:auth 创建所需文件,再执行 php artisan migrate 创建所需数据库结构即可。

深入了解,请参考用户认证文档。

接下来我们在浏览器中打开你的应用,会发现右上角多了登录和注册,我们随意注册一个测试用户以备使用。

(4)接下来,配置频道认证。

还记得第(1)步的 routes/channels.php 吗,我们打开此文件。并新增一条频道认证规则。

注意:虽然此文件位于 routes 目录下,但并不是路由文件!在此定义后并不能访问,且无法使用分组、中间件。所有的验证路由都已经在 Broadcast::routes() 中定义。

Broadcast::channel(&#39;orderStatus&#39;, function ($user, $value) {
    return true; // or false
});
ログイン後にコピー

由于 Broadcast 已经使用 Auth 进行用户登录认证,所以我们只需无条件返回 true 即可实现:任何已登录用户都可以收听此频道。

(5)认证部分我们已经配置完成,接下来将共有频道的定义改为私有。

修改广播消息基于的事件类 app/Events/OrderShipped.php:

public function broadcastOn()
{
    return new PrivateChannel(&#39;orderStatus&#39;); // 私有频道
}
ログイン後にコピー

修改客户端收听代码 resources/assets/js/bootstrap.js。

Echo.private(`orderStatus`) // 私有频道
    .listen(&#39;OrderShipped&#39;, (e) => {
        console.log(e);
    });
ログイン後にコピー

(6)接下来,再次运行 Laravel Echo Server。使用浏览器打开你的应用首页,在未登录状态,可以看到 Echo Server 输出一个来自 Laravel 的 AccessDeniedHttpException 异常,提示用户认证失败,无法收听频道。

登录后,即可获得与上一节相同的预期结果。

(7)如上,我们成功实现所有登录用户均可收听私有频道。那么如何实现某部分用户可以收听,某部分用户不可以收听频道?例如:某个用户均有属于自己的频道,他只能收听自己的频道。请继续往下看。

首先,修改广播消息基于的事件类 app/Events/OrderShipped.php。你需要将频道命名修改为动态的值。

public $userId; // 新增成员变量 userId,不要忘记在构造函数内对其进行赋值

public function broadcastOn()
{
    return new PrivateChannel(&#39;orderStatus-&#39; . $this->userId); // 动态命名私有频道
}
ログイン後にコピー

其次,修改第(4)步中的 routes/channels.php 文件。Broadcast 支持使用通配符匹配「某一类」频道进行验证。

Broadcast::channel(&#39;orderStatus-{userId}&#39;, function ($user, $value) {
    // $user    Auth认证通过的用户模型实例
    // $value   频道规则匹配到的 userId 值
    return $user->id == $value; // 可使用任意条件验证此用户是否可监听此频道
});
ログイン後にコピー

最后别忘记修改前端收听的频道名称。

再次打开浏览器测试即可发现:在本例中,若客户端收听的频道不匹配当前用户 ID,则会报错。

(8)如上,我们成功实现对私有频道进行自定义规则的认证;但如果我们没有使用 Auth 认证系统,或采用了自己编写的用户认证中间件,该如何兼容呢?

经过一番源码调试,我发现 Broadcast 在 vendor/laravel/framework/src/Illuminate/Broadcasting/Broadcasters/ 文件夹下定义的 Broadcaster 内调用 $request->user() 进行了用户验证。

例如我们采用的 PusherBroadcaster.php:

/**
 * Authenticate the incoming request for a given channel.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return mixed
 * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
 */
public function auth($request)
{
    if (Str::startsWith($request->channel_name, [&#39;private-&#39;, &#39;presence-&#39;]) &&
        ! $request->user()) {
        throw new AccessDeniedHttpException;
    }
    $channelName = Str::startsWith($request->channel_name, &#39;private-&#39;)
                        ? Str::replaceFirst(&#39;private-&#39;, &#39;&#39;, $request->channel_name)
                        : Str::replaceFirst(&#39;presence-&#39;, &#39;&#39;, $request->channel_name);
    return parent::verifyUserCanAccessChannel(
        $request, $channelName
    );
}
ログイン後にコピー

由此可得,我们有两种方式实现。

第一种

直接注释 throw new AccessDeniedHttpException,并修改 app/Providers/BroadcastServiceProvider.php。

Broadcast::routes() 可接收一个参数。在 vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastManager.php 可查看其定义:

/**
 * Register the routes for handling broadcast authentication and sockets.
 *
 * @param  array|null  $attributes
 * @return void
 */
public function routes(array $attributes = null)
{
    if ($this->app->routesAreCached()) {
        return;
    }
    $attributes = $attributes ?: [&#39;middleware&#39; => [&#39;web&#39;]];
    $this->app[&#39;router&#39;]->group($attributes, function ($router) {
        $router->post(&#39;/broadcasting/auth&#39;, &#39;\\&#39;.BroadcastController::class.&#39;@authenticate&#39;);
    });
}
ログイン後にコピー

通过源码可知:此参数等效于 Route::group() 的第一个参数。所以我们只要将其修改为如下形式:

Broadcast::routes([&#39;middleware&#39; => [&#39;yourMiddleware&#39;])
ログイン後にコピー

并在中间件内进行用户认证;如未登录,照常抛出 AccessDeniedHttpException 异常即可。

第二种

在 vendor/laravel/framework/src/Illuminate/Http/Request.php 可以查看到 $request->user() 的定义。

/**
 * Get the user making the request.
 *
 * @param  string|null  $guard
 * @return mixed
 */
public function user($guard = null)
{
    return call_user_func($this->getUserResolver(), $guard);
}
ログイン後にコピー

如上可知,它使用 $this->userResolver 内的匿名函数获取用户模型。所以我们只需要在AuthServiceProvider 注册后,Broadcast 认证前,替换掉其 userResolver 即可。

例如:继承 Illuminate\Auth\AuthServiceProvider(vendor/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php),并重写 registerRequestRebindHandler 方法及构造函数,添加如下代码。

$request->setUserResolver(function ($guard = null) use ($app) {
    // 在此判断用户登录状态
    // 若登录,请返回 App\User 或其它用户模型实例
    // 未登录,请返回 null
});
ログイン後にコピー

修改 config/app.php,使用改造过的 AuthServiceProvider 类替换原服务提供者即可。

5、总结

至此,你已经建立对 Laravel Boardcast 的基本认识,成功入门「广播系统」。

另外,Laravel 5.6 新增一条关于 Broadcast 的新特性,避免在 routes/channels.php 文件内编写众多闭包导致的难以维护。详情可查看:Laravel 5.6 新版特性。

其实,本文只不过抛砖引玉而已。对于部署到生产环境,仍然存在许多问题,例如:

与常见 PHP 应用不同,广播基于 WebSocket 长连接;那么如何确保通信稳定性,如何剔除死链?

为了确保应用访问速度,广播通常是异步执行的;那么如何配置事件队列?如何将队列配置为异步?

如何确保 Laravel Echo Server 进程稳定运行?如何处理异常?是否需要关闭 Debug 模式?

如何确保 Laravel Echo 与服务端连接稳定?是否需要定时检查?如何捕捉并完善地处理所有异常?

客户端收听私有频道,若被服务器拒绝,是否需要断开连接?如何给予用户友好地提示?

……

当然,这些问题本文没有提到,但网络上已经有无数成熟、便捷的解决方案;更多高级用法也可以参照本文最初列出的官方文档。

以上就是本篇文章的全部内容了,更多内容请关注laravel入门教程!

相关文章推荐:

Laravel框架中管道设计模式之中间件的基本工作原理

Laravel框架实现发送短信验证功能代码,laravel发送短信

相关课程推荐:

全方位解读Laravel框架及实战视频教程

2017年最新のおすすめLaravelビデオチュートリアル5本

以上がLaravelフレームワークの組み込みブロードキャスト機能がクライアントとのリアルタイム通信を実現する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

どちらが良いのか、DjangoとLaravel? どちらが良いのか、DjangoとLaravel? Mar 28, 2025 am 10:41 AM

DjangoとLaravelはどちらもフルスタックのフレームワークです。 DjangoはPython開発者や複雑なビジネスロジックに適していますが、LaravelはPHP開発者とエレガントな構文に適しています。 1.DjangoはPythonに基づいており、迅速な発展と高い並行性に適した「バッテリーコンプリート」哲学に従います。 2. LaravelはPHPに基づいており、開発者エクスペリエンスを強調しており、小規模から中規模のプロジェクトに適しています。

LaravelとThe BackEnd:Webアプリケーションロジックの電源 LaravelとThe BackEnd:Webアプリケーションロジックの電源 Apr 11, 2025 am 11:29 AM

Laravelはバックエンドロジックでどのように役割を果たしますか?ルーティングシステム、Eloquentorm、認証と承認、イベントとリスナー、パフォーマンスの最適化を通じてバックエンド開発を簡素化および強化します。 1.ルーティングシステムにより、URL構造の定義とリクエスト処理ロジックが可能になります。 2.Eloquentormは、データベースの相互作用を簡素化します。 3.認証および承認システムは、ユーザー管理に便利です。 4.イベントとリスナーは、ゆるく結合したコード構造を実装します。 5.パフォーマンスの最適化により、キャッシュとキューイングを通じてアプリケーションの効率が向上します。

Laravelは紹介例 Laravelは紹介例 Apr 18, 2025 pm 12:45 PM

Laravelは、Webアプリケーションを簡単に構築するためのPHPフレームワークです。次のような強力な機能を提供します。インストール:Laravel CLIを作曲家にグローバルにインストールし、プロジェクトディレクトリにアプリケーションを作成します。ルーティング:ルート/web.phpのURLとハンドラーの関係を定義します。ビュー:リソース/ビューでビューを作成して、アプリケーションのインターフェイスをレンダリングします。データベース統合:MySQLなどのデータベースとのすぐ外側の統合を提供し、移行を使用してテーブルを作成および変更します。モデルとコントローラー:モデルはデータベースエンティティを表し、コントローラーはHTTP要求を処理します。

どちらがより良いPHPですか、それともLaravelですか? どちらがより良いPHPですか、それともLaravelですか? Mar 27, 2025 pm 05:31 PM

LaravelはPHPベースのフレームワークであるため、PHPとLaravelは直接匹敵するものではありません。 1.PHPは、シンプルで直接的であるため、小規模プロジェクトや迅速なプロトタイピングに適しています。 2。LARAVELは、豊富な機能とツールを提供するため、大規模なプロジェクトや効率的な開発に適していますが、急な学習曲線があり、純粋なPHPほど良くない場合があります。

Laravelはフロントエンドですか、それともバックエンドですか? Laravelはフロントエンドですか、それともバックエンドですか? Mar 27, 2025 pm 05:31 PM

laravelisabackendframeworkbuiltonphp、designforwebapplicationdevelopment.itfocusonserver-sidelogic、databasemanagement、およびapplicationStructure、およびbueithedendtechnologiesvue.jsorreactforfull-stackdevelymentと統合されていること。

Laravelユーザーログイン機能 Laravelユーザーログイン機能 Apr 18, 2025 pm 12:48 PM

Laravelは、ユーザーモデル(Eloquentモデル)の定義、ログインフォームの作成(ブレードテンプレートエンジン)、ログインコントローラーの作成(認証\ログインコントローラーの継承)、ログイン要求の検証(Auth ::試行)の検証など、ユーザーログイン機能を実装するための包括的なAuthフレームワークを提供します。ヘッダー。さらに、AUTHフレームワークは、パスワードのリセット、電子メールの登録と検証などの機能も提供します。詳細については、Laravelのドキュメントを参照してください:https://laravel.com/doc

Laravelを学ぶ方法Laravelを無料で学ぶ方法 Laravelを学ぶ方法Laravelを無料で学ぶ方法 Apr 18, 2025 pm 12:51 PM

Laravelフレームワークを学びたいが、資源や経済的圧力に苦しんでいないのですか?この記事では、Laravelの無料学習を提供し、オンラインプラットフォーム、ドキュメント、コミュニティフォーラムなどのリソースを使用して、PHP開発の旅から習得するための堅実な基盤を築く方法を教えてくれます。

Laravelフレームワークのスキル共有 Laravelフレームワークのスキル共有 Apr 18, 2025 pm 01:12 PM

継続的な技術の進歩のこの時代において、現代のプログラマーにとって高度なフレームワークをマスターすることが重要です。この記事では、Laravelフレームワークであまり知られていないテクニックを共有することで、開発スキルを向上させるのに役立ちます。エレガントな構文と幅広い機能で知られるこの記事では、その強力な機能を掘り下げ、効率的で保守可能なWebアプリケーションを作成するための実用的なヒントとコツを提供します。

See all articles