私有频道不与Laravel echo服务器

时间:2017-04-10 07:19:36

标签: laravel websocket socket.io laravel-5.4 laravel-echo

我在控制台上收到了这个JS错误:

app.js:167未捕获的ReferenceError:未定义receiverId

以下是我的完整代码:

PrivateChatController:

event(new PrivateMessageEvent($chat, $receiverId));

PrivateMessageEvent:

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\User;
use App\PrivateChat;

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

    public $privateChat, $receiverId;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(PrivateChat $privateChat, $receiverId)
    {
        $this->privateChat = $privateChat;
        $this->receiverId = $receiverId;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('private-chat.' . $this->receiverId);
    }
}

Bootstrap.js

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});

window.Echo.private(`private-chat.${receiverId}`)
    .listen('PrivateMessageEvent', (e) => {
        console.log(e);
});

channels.php

Broadcast::channel('private-chat.{receiverId}', function ($user, $receiverId) {
    return true; // this is just for debugging to allow anyone to listen on this channel
    //return $user->id === $receiverId;
});

laravel回波-server.json

{
    "authHost": "http://localhost",
    "authEndpoint": "/broadcasting/auth",
    "clients": [],
    "database": "redis",
    "databaseConfig": {
        "redis": {},
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": null,
    "port": "6001",
    "protocol": "http",
    "socketio": {},
    "sslCertPath": "",
    "sslKeyPath": ""
}

在后台队列中:工作 laravel-echo-server 已在运行

在触发该事件后,我在laravel-echo-server控制台上收到此消息:

Channel: private-private-chat.
Event: App\Events\PrivateMessageEvent
CHANNEL private-private-chat.

备注:

我花了超过10个小时,尽我所能,但没有运气。

由于

4 个答案:

答案 0 :(得分:3)

您可以将REDIS_PREFIX设置为NULL以删除前缀,否则如果前缀具有值,则必须在回显服务器配置中设置keyPrefix

如果REDIS_PREFIX = NULL,则不要添加keyPrefix


重要通知

使用broadcastAs()时,对listen('')的呼叫必须以DOT开头

目前尚不知道使用keyPrefix时的行为,如果使用前缀设置,请评论DOT要求的结果。

https://laravel.com/docs/6.x/broadcasting#broadcast-name

public function broadcastAs()
{
    return 'server.created';
}
.listen('.server.created', function (e) {
    ....
});

我会自行检查DOT + PREFIX组合,但是如果我再继续使用它,我会感到Laravel Echo会给我心脏病发作。


如果您不使用broadcastAs(),则命名将回退到事件类名称,在这种情况下,没有注入DOT前缀,请参见以下设置:

laravel-echo-server.json

{
    "host": "127.0.0.1",
    "port": "6001",
    "protocol": "http",

    "database": "redis",

    "databaseConfig": {
        "redis": {
            "host": "127.0.0.1",
            "port": 6379,
            "db": 0,
            "keyPrefix": "VALUE OF REDIS_PREFIX"
        }
}

/app/Events/MyExample.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;

class MyExample implements ShouldBroadcastNow
{

  private $id;

  public $payload;

  public function __construct($id, $payload)
  {
    $this->id = $id;
    $this->payload = $payload;
  }

  public function broadcastOn()
  {
    return new PrivateChannel('example.' . $this->id);
  }

}

触发事件(PHP)


use App\Events\MyExample

$payload = [
 'duck' => 'sauce',
 'Bass' => 'Epic'
];

event(new MyExample($id, $payload))

收听事件(JavaScript)

Echo.private(`example.${id}`).listen('MyExample', event => {

  console.log('payload', event.payload)

})

答案 1 :(得分:1)

尝试更改此行:

$this->$receiverId = $receiverId;

到这一行:

$this->receiverId = $receiverId;

在您的PrivateMessageEvent __construct()

更新:

尝试使用像这样的固定频道ID:

window.Echo.private('private-chat.1')

我建议您也使用在线频道,也是私有的但具有更多功能,即:

Echo.join('private-chat.1')
   .listen('PrivateMessageEvent', (e) => {
    console.log(e);
});

如果你使用像你使用的dinamic频道号码,即:

window.Echo.private(`private-chat.${receiverId}`)

你必须在javascript中给receiverId一个值,这个声明是一个通用的房间监听器,但是应该定义receiverId,$ {receiverId}是一个字符串插值。

您可以在插入app.js之前在模板中定义receiverId,例如,使用刀片语法:

<script>
   receiverId = {{ $receiverId }};
</script>

另一个想法:我想清楚的是,在上面的所有代码中,receiverId表示客户想要加入的聊天/房间的ID而不是接收用户的ID。

答案 2 :(得分:0)

尝试代替SELECT number, SUM(amount) as SumAm FROM products --WHERE number IN ('M6412', 'M6545') i think you dont need where clause group by number

event(new PrivateMessageEvent($chat, $receiverId));

答案 3 :(得分:0)

您需要做一些事情。

1)从频道名称的开头删除所有“ private-”。这些由各种库(例如socket.io/laravel-echo)在后台处理。如果您查看任何调试输出,则将在通道名称的前面看到“ private-”,但无需添加这些名称。

2)如果您正在使用redis,请确保REDIS_PREFIX在.env文件中设置为空字符串。默认情况下,它设置为“ laravel_database”之类的东西,这会弄乱通道名称。

REDIS_PREFIX=

3)确保您的laravel-echo服务器正在运行(以及redis / pusher)。另外,您还需要确保队列工作器正在运行。就我而言,当我运行redis时,我必须运行:

php artisan queue:work redis