【问题标题】:Laravel echo server not working in production serverLaravel 回显服务器在生产服务器中不起作用
【发布时间】:2019-01-27 09:56:25
【问题描述】:

我在 socket.io 作为带有 laravel echo 的广播公司时遇到问题。

我尝试了什么:

php artisan cache:clear
php artisan config:clear

我可以看到用户在日志中连接:

0|Socket-Connection  | [11:17:00 AM] - ********** joined channel: test-channel
0|Socket-Connection  | [11:17:01 AM] - ********** authenticated for: private-user.1
0|Socket-Connection  | [11:17:01 AM] - ********** joined channel: private-user.1

我的队列正在运行并正确记录所有事件。

我可以在 redis 控制台中完美地看到 redis 我的事件和数据库通知。

但是没有事件被广播,我在 laravel-echo-server 控制台中看不到它们。一切都在我的本地主机中运行,但在生产中却没有,我失去了理智。

这是我的 laravel echo JS:

if (typeof io !== 'undefined') {
    console.log(window.location.origin);
    window.Echo = new Echo({
        broadcaster: 'socket.io',
        host: window.location.origin + ':6001',
        auth: {
            headers: {
                Authorization: 'Bearer ' + bearerToken,
            },
        }
    });
    window.Echo.private('user.' + user_id).notification((notification) => {
        console.log(notification);
    });
}

在我的用户模型上,我定义了这个:

/**
* @return string
*/
public function receivesBroadcastNotificationsOn()
{
    return 'user.' . $this->id;
}

在我的频道中,我有这个:

Broadcast::channel('user.{id}', function ($user, $id) {
    return (int)$user->id === (int)$id;
});

这是我的 echo 服务器配置,所有路径都正确。我在本地主机上测试了相同的文件,一切正常:

var echo = require('laravel-echo-server/dist');

echo.run({
    "appKey": "myappkey",
    "authHost": "https://url",
    "authEndpoint": "/broadcasting/auth",
    "database": "redis",
    "clients": [
        {
            "appId": "myappid",
            "key": "mykey"
        }
    ],
    "databaseConfig": {
        "redis": {
            "port": "6379",
            "host": "myhost",
            "password": "mysupersecretpassword"
        },
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": "url",
    "port": "6001",
    "protocol": "https",
    "referrers": [],
    "sslCertPath": "/path/to/certificate.pem",
    "sslKeyPath": "/path/to/key",
    "verifyAuthPath": true,
    "verifyAuthServer": false
});

我的 redis 日志在发布数据库通知时显示此内容

1534840681.110359 [0 "IP ADDRESS HERE"] "PUBLISH" "private-user.2" "{\"event\":\"Illuminate\\\\Notifications\\\\Events\\\\BroadcastNotificationCreated\",\"data\":{\"title\":\"Ravim CONVULEX 50MG\\/ML  staatust muudeti\",\"notification_type\":\"element-soft-delete\",\"message\":\"Ravimi CONVULEX 50MG\\/ML  staatust muutis kasutaja Kalle \",\"url\":\"https:\\/\\/www.app.riskomed.com\\/admin\\/brands\\/all\",\"id\":\"30c37d0d-c39b-41bf-93fc-afa0c78ca9db\",\"type\":\"App\\\\Notifications\\\\API\\\\Management\\\\Medical\\\\Brands\\\\BrandSoftDeleteNotification\",\"socket\":null},\"socket\":null}"

编辑

这是我的通知

        /**
     * Get the notification's delivery channels.
     *
     * @param  mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail', 'database', 'broadcast'];
    }

【问题讨论】:

  • 你能检查你是否在打开的 ob_start() 缓冲区下调用 echo 吗?
  • @Miguel 我在哪里可以做到这一点?
  • 可能这不是解决问题的最佳方法,但我会检查您正在使用的 lavarel 模块内部是否存在使用此缓冲区的某个点。因为该功能正在获取标准输出,然后再检索它
  • 当您在本地测试时,您是否在echo.run() 中使用了相同的 authHosthostport 设置作为 prod ?我想知道这是否是防火墙或类似的访问问题...
  • @Rich 端口和 authost 相同,host 因域名不同。我不知道这是否是防火墙问题,因为我可以很好地做普通的套接字服务器并连接并从客户端接收数据。

标签: php laravel redis socket.io laravel-echo


【解决方案1】:

我看到您在生产服务器中使用“https”协议,因此您需要定义“sslCertPath”和“sslKeyPath”:

来自文档

使用 SSL 运行

  • 您的客户端实现必须从 HTTPS。
  • 服务器配置必须设置服务器主机使用 https。
  • 服务器配置应包括您的 ssl 证书和位于服务器上的密钥的路径。

【讨论】:

  • 一切都完成了。通过 SSL。我只是写了“path/to”,因为我不想暴露我的服务器路径
  • 好的,正如我在日志中看到的那样,您收听“private-user.1”频道,但日志中的 redis 广播到“PUBLISH”“private-user.2”,问题可能出在这里吗?
  • 刚刚复制和示例:两个用户在线。这就是用户 2 的原因。
【解决方案2】:

如果您看到用户加入频道,那么很可能是设置正确。您只需要为您的console.log(notification) 调用广播通知即可工作,因为您专门在用户频道上调用通知功能。详情请见https://laravel.com/docs/5.6/broadcasting#notifications

带有通知的广播:

//Create a new notification with artisan, e.g. php artisan make:notification testNotification

class testNotification extends Notification {

    ...

    public function via($notifiable)
    {
        return ['broadcast'];
    }

    ...

    public function toBroadcast($notifiable) {
        return new BroadcastMessage([
            'message' => 'TEST',
        ]);
    }
}

然后,当您准备好广播您的消息时,只需通知用户:

$user->notify(new testNotification());

编辑:

另外,请确保您的用户模型中有 Notifiable 特征:

class User extends Authenticatable
{
    use Notifiable;

    ...
}

【讨论】:

  • 确保您在通知类中定义toBroadcast($notifiable) 函数并返回BroadcastMessage,因为我在您的编辑中没有看到它。您需要以您要测试的用户身份登录并导航到您有 Echo 通知调用的页面,然后设置测试路由以在您登录的用户上调用 $user->notify(new testNotification()); 并访问该页面一个单独的窗口/选项卡。
  • 另外,请确保您的用户模型具有 Notifiable 特征。
  • 它具有 Notifiable trait!
猜你喜欢
  • 2021-07-09
  • 2019-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多