支持 Laravel.io 的持续开发 →

Laravel WebSockets 服务器使用 Valet 和 SSL

2022年2月23日 阅读时间约6分钟

序言

感谢Marcel Pociot等人为Laravel优秀的包做出了巨大贡献。感谢DevMarketer提供的详细步骤

然而...

所以,我已经很长时间想尝试使用Laravel Echo和Pusher来实现广播和实时通知。但由于主要在开发不依赖外部服务的内部应用,所以我倒霉透顶了。自从Marcel在2021年Laracon Online Winter上关于“理解Laravel广播”的精彩演讲后,我就迫不及待地想深入学习这个话题。

所以,我打开了新的终端窗口,输入laravel new websockets(用于创建新的Laravel应用),并跟随https://beyondco.de/docs/laravel-websockets/中提供的详细步骤。

我不知道我在哪里出了问题,但一切都没有按预期工作。结果是我本地的Valet和自签名SSL证书设置出了问题(2021年了,谁还用HTTP呢,对吧?)

所以,这里是我的指南,介绍了如何在Valet和SSL的帮助下运行自己的本地WebSockets服务器。

让我们开始吧!

先决条件

我正在运行Laravel Valet 2.14.1和PHP 8.0.3

设置

从头开始,我们将创建一个新的Laravel项目(本文撰写时为Laravel 8.36.2)

$ laravel new websockets

需要一个全新的SSL证书吗?

$ cd websockets
$ valet secure
Restarting nginx...
The [websockets.test] site has been secured with a fresh TLS certificate.

让我们更改.env文件中应用的URL

APP_URL=https://websockets.test

我们需要拉取beyondcode/laravel-websockets

composer require beyondcode/laravel-websockets

现在让我们发布迁移(用于统计)和配置文件

$ php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"

让我们发布WebSocket配置文件

$ php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"

运行迁移(您应该先设置数据库并相应地更新 .env文件)

$ php artisan migrate

配置

我们现在准备开始,让我们看看我们的配置文件。首先,我们需要更改.env中的BROADCAST_DRIVER

...

BROADCAST_DRIVER=pusher

...

PUSHER_APP_ID=1 // this can be anything you want
PUSHER_APP_KEY=some-key // this can also be anything you want
PUSHER_APP_SECRET=some-secret // also this
PUSHER_APP_CLUSTER=mt1 // doesn't matter

"为什么是pusher?"你可能这么问。我不想用外部服务,对吧?你说得对,我们实际上并没有使用pusher。因为laravel-websockets使用与pusher相同的API,所以我们在使用pusher驱动程序。

现在,在config/broadcasting.php中找到connections

'connections' => [

    'pusher' => [
        'driver' => 'pusher',
        'key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'app_id' => env('PUSHER_APP_ID'),
        'options' => [
            'cluster' => env('PUSHER_APP_CLUSTER'),
            'useTLS' => true,
            'host' => '127.0.0.1', // add this
            'port' => 6001, // and this
            'encrypted' => true, // also this
            'scheme' => 'https', // and this
            'curl_options' => [ // since we're only doing stuff locally this is fine
                CURLOPT_SSL_VERIFYHOST => 0,
                CURLOPT_SSL_VERIFYPEER => 0,
            ],
        ],

几乎完成了!让我们看看config/websockets.php

'ssl' => [
    /*
     * Path to local certificate file on filesystem. It must be a PEM encoded file which
     * contains your certificate and private key. It can optionally contain the
     * certificate chain of issuers. The private key also may be contained
     * in a separate file specified by local_pk.
     */
    'local_cert' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT', null),

    /*
     * Path to local private key file on filesystem in case of separate files for
     * certificate (local_cert) and private key.
     */
    'local_pk' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_PK', null),

我们需要在.env中设置这些环境变量以使SSL正常工作。

.env中添加以下条目

LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT=/absolute/path/to/your/crt/file
LARAVEL_WEBSOCKETS_SSL_LOCAL_PK=/absolute/path/to/your/key/file

根据您的设置,这些文件将 reside in ~/.config/valet/Certifificates,在我的情况下,它看起来像这样

LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT=/Users/maze/.config/valet/Certificates/websockets.test.crt
LARAVEL_WEBSOCKETS_SSL_LOCAL_PK=/Users/maze/.config/valet/Certificates/websockets.test.key

现在我们准备好使用以下命令启动WebSocket服务器

$ php artisan websockets:serve

如果一切顺利,你应该在你的终端中看到以下输出

Starting the WebSocket server on port 6001...

打开浏览器,转到位于https://websockets.test/laravel-websockets的WebSocket仪表板,并单击Connect

你应该看到一些类型为subscribed的事件,这意味着服务器正在运行。您的终端也将充满了调试信息。

太棒了对吧?但是等等,还有更多!我们能不能将前端连接起来,每当我们分派一个事件时都会弹出警告窗口?这将非常烦人,但为了示例,足够了。

前端

我们需要拉入两个NPM包

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

又是Pusher包?好吧,是的,同一个API,还记得吗?

现在让我们在resources/js/bootstrap.js中设置Laravel Echo

import Echo from 'laravel-echo';

window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    forceTLS: true,
    wsHost: window.location.hostname,
    wssPort: 6001,
});

编译你的前端资源

$ npm run dev

因为我们使用的是纯净的Laravel安装,所以我们只需向位于resources/views/welcome.blade.php的欢迎视图中添加一些JS即可

        <script src="{{ mix('js/app.js') }}"></script>
        <script>
            Echo.channel('home')
                .listen('Message', (e) => alert(e.message));
        </script>
    </body>
</html>

这将监听home频道,并将事件广播到该频道时显示消息。说到事件,我们还需要创建一个,所以

$ php artisan make:event Message

app/Events/Message.php应该像这样

<?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 Message implements ShouldBroadcast // this needs to be added
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message; // our message

    public function __construct(string $message)
    {
        $this->message = $message;
    }

    public function broadcastOn()
    {
        return new Channel('home');
    }
}

这个事件将在分派后通过home频道广播,并且Laravel Echo将监听这个事件被分派。

现在,打开一个浏览器窗口,将其指向本地应用程序的索引页面,位于https://websockets.test,你应该看到欢迎页面。

在您的终端中打开Laravel Tinker。我们使用Tinker来快速分派事件,而无需编写大量的应用程序逻辑。

$ php artisan tinker
Psy Shell v0.10.8 (PHP 8.0.3 — cli) by Justin Hileman
>>>

然后手工启动事件

$ php artisan tinker
Psy Shell v0.10.8 (PHP 8.0.3 — cli) by Justin Hileman
>>> App\Events\Message::dispatch('this is awesome')

现在,当你按下回车键时,事件将被分派,你应该在浏览器中看到一个警告弹出。我们完成了!这不很难,不是吗?

下一步是什么?

你可以在https://github.com/mazedlx/laravel-websockets-example查看这个示例的代码。

别忘了看看https://pusher.com/https://ably.com/,他们都提供了慷慨的免费计划。

还可以访问https://github.com/beyondcode/laravel-websockets并给仓库点赞,关注https://twitter.com/marcelpociot

如果您想查看一个现实生活中的示例,我的好朋友Christoph Rumpel不久前写了一篇关于使用Laravel Websockets包实现实时通知的博客文章。

最后更新时间为1年前。

drivesvints喜爱这篇文 章

1
喜欢这篇文章?让作者知道,并且给他们一个赞!
mazedlx (mazedlx) 全栈开发者。💖 爱好Laravel和TALL Stack。爸爸和烧烤爱好者。

你可能还会喜欢以下文章

2024年3月11日

如何使用Larastan把您的Laravel应用从0到9级提升

使用Larastan在您的Laravel应用执行前找到错误是可能的,因为...

阅读文章
2024年7月19日

在不使用特质的情况下标准化API响应

我注意到一个问题,大多数针对API响应创建的库都使用特质实现,...

阅读文章
2024年7月17日

在Laravel项目中通过Discord通知收集反馈

如何创建一个反馈模块并在接收到消息时在Laravel项目中接收Discord通知

阅读文章

我们非常感谢这些 令人惊叹的公司 对我们提供的支持

在这里放置您的标志?

Laravel.io

解决问题、知识分享和社区建设的Laravel门户。

© 2024 Laravel.io - 所有权利保留。