【问题标题】:Laravel Echo with Pusher not receiving messages on private channel带有 Pusher 的 Laravel Echo 未在私人频道上接收消息
【发布时间】:2020-04-14 09:58:31
【问题描述】:

每次我切换到私人频道时,浏览器都没有收到任何内容,但是当只使用标准频道时,它可以工作。我当前的设置包括一个用于前端的 Vue CLI 应用程序和一个 Laravel API 作为后端,使用 Laravel Passport 进行身份验证。

这是用于连接 Pusher 的代码。

import LaravelEcho from 'laravel-echo';

// ...

export const Echo = new LaravelEcho({
  broadcaster: 'pusher',
  key: pusherKey,
  cluster,
  encrypted: true,
});

Echo.connector.pusher.config.authEndpoint = `${baseURL}/broadcasting/auth`;

store.watch((state: any) => state.$auth.token, (token: string) => {
  Echo.connector.pusher.config.auth.headers['Authorization'] = `Bearer ${token}`;
});

store.watch((state: any) => state.$auth.user, (n: any, o: any) => {
  if (n) {
    console.log(`App.User.${n.id}`); // This is being logged to the console App.User.1
    Echo.private(`App.User.${n.id}`)
      .listen('.friend.request', (e: any) => {
        console.log({ e });
      });
  }
});

这是通道路由文件:

<?php

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

事件的精简版。

<?php

namespace App\Events;

// ...

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

    // ...

    public function broadcastOn()
    {
        return new PrivateChannel("App.User.{$this->friend->id}");
    }

    // ...
}

我已经设置了这条测试路线:

<?php

Route::get('/', function (Request $request) {
    event(new FriendRequestSent(User::find(1), User::find(1)));
});

运行Echo.private()... 代码后,我可以在我的 Pusher 仪表板中看到以下内容:

然后在从/ 路由触发事件后:

最后,Pusher 接收到事件,但控制台中没有任何显示:

但是,如果我将new PrivateChannel(...) 更改为new Channel(...),然后使用Echo.channel 而不是Echo.private,它将开始在控制台中显示一些内容。

有人知道为什么会这样吗?


对此的更新,我找到了这个网页:Pusher Docs - Debugging

Pusher :  : ["Event sent",{"event":"pusher:subscribe","data":{"auth":"some_auth_code_returned_from_api_broadcasting_auth","channel":"private-App.User.1"}}]

Pusher :  : ["Event recd",{"event":"pusher_internal:subscription_succeeded","channel":"private-App.User.1","data":{}}]

Pusher :  : ["No callbacks on private-App.User.1 for pusher:subscription_succeeded"]

我可以通过最终输出看到 No callbacks on private-App.User.1... 可能导致问题,但我能找到的唯一内容是:

  1. 更改为BROADCAST_DRIVER=pusher
  2. channels.php 中尝试此代码:
<?php

// Notice {userId} rather than {id}.
Broadcast::channel('App.User.{userId}', function ($user, $userId) {
    return (int) $user->id === (int) $userId;
});

我现在已经用 Socket.IO 尝试了这个,我得到了相同的结果:

Socket.IO 控制台输出:

[6:36:11 AM] - Preparing authentication request to: http://isapi.test
[6:36:11 AM] - Sending auth request to: http://isapi.test/api/broadcasting/auth
[6:36:12 AM] - gT9--_C_2c-KwoxLAAAE authenticated for: private-App.User.1
[6:36:12 AM] - gT9--_C_2c-KwoxLAAAE joined channel: private-App.User.1

我的 Socket.IO 配置:

import io from 'socket.io-client';

(window as any).io = io;

export const Echo = new LaravelEcho({
  broadcaster: 'socket.io',
  host: `${baseURL.substr(0, baseURL.length - 4)}:6001`,
  encrypted: true,
});

Echo.connector.socket.io.opts.authEndpoint = `${baseURL}/broadcasting/auth`;

store.watch(
  (state: any) => state.$auth.token,
  (token: string) => {
    Echo.connector.socket.io.opts.auth.headers.Authorization = `Bearer ${token}`;
  },
);

所以我创建了一个全新的 Vue 和 Laravel 安装,具有以下依赖项:

Laravel:

  • 护照
  • 巴里 CORS
  • 推送服务器

Vue:

  • TypeScript 安装
  • 我的自定义 HTTP 包装器(仅包装 fetch 和 axios)

而且它很有效,所以我只需要找出我做的不同之处,看看我是否能以这种方式解决它。如果您想查看此测试代码,我已将其放在此存储库中。

https://github.com/kingga/stackoverflow-59449785

【问题讨论】:

    标签: php laravel sockets pusher laravel-echo


    【解决方案1】:

    与往常一样,这是一个非常简单但被忽视的解决方案。

    我有两个store.watch;一个在令牌上,一个在用户上。用户必须先运行,然后再运行令牌,导致在连接到专用通道时无法设置令牌。例如

    store.watch(
      (state: any) => state.$auth.token,
      (token: string) => {
        Echo.connector.pusher.config.auth.headers.Authorization = `Bearer ${token}`;
      },
    );
    
    store.watch(
      (state: any) => state.$auth.user,
      (n: any, o: any) => {
        if (n) {
          // Added this line to fix the issue.
          Echo.connector.pusher.config.auth.headers.Authorization = `Bearer ${store.state.$auth.token}`;
          Echo.private(`App.User.${n.id}`).listen(
            '.friend.request',
            (data: any) => {
              // store.state.$friends.requests = data;
              console.log({ data });
            },
          );
        } else if (o) {
          Echo.private(`App.User.${o.id}`)
            .stopListening('.friend.request');
        }
      },
    );
    

    【讨论】:

      猜你喜欢
      • 2019-06-04
      • 2017-05-12
      • 2023-04-05
      • 2019-11-05
      • 2017-11-27
      • 2018-01-24
      • 2020-11-22
      • 2016-11-06
      • 2018-02-23
      相关资源
      最近更新 更多