带有私人频道的 Laravel Echo SocketIO

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43898564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:56:46  来源:igfitidea点击:

Laravel Echo SocketIO with private channel

laravelsocketslaravel-5socket.iolaravel-echo

提问by Diego Cortés

Hi everyone I working with Laravel Echo and SocketIO without Vue only jquery, but I have a problem with private channels here I show you that I have two events normal and private channel the normal channel (todocanales of my event HolaEvent) work fine when I lunch the event

大家好,我使用 Laravel Echo 和 SocketIO 而没有仅使用 Vue 的 jquery,但是我在这里的私人频道有问题我向您展示我有两个事件正常和私人频道正常频道(我的事件 HolaEvent 的 todocanales)在我午餐时工作正常事件

use App\Events\HolaEvent;

Route::get('/fire', function () {

    $data = [
        'type'    => 'erhelloror',
        'title'   => 'new article has been published',
        'message' => 'check it out',
        'url'     => 'url',
    ];
    event(new HolaEvent($data));
    return 'done';
});

and in my laravel echo server console show me:

并在我的 Laravel 回声服务器控制台中向我展示:

[03:04:47] - 5s6214Rlv51NUgnDAAAA joined channel: todocanales
[03:04:48] - QpxGvCjmaezgHn3aAAAB authenticated for: private-like-received.2jzwpAg1
[03:04:48] - QpxGvCjmaezgHn3aAAAB joined channel: private-like-received.2jzwpAg1
Channel: todocanales
Event: App\Events\HolaEvent
CHANNEL todocanales

and in the browser console, I get

在浏览器控制台中,我得到

~~~ Object {data: Object, socket: null} ~~~

~~~对象{数据:对象,套接字:空}~~~

all perfect, BUT with the privateChannel I have the problem Laravel Echo server don't made anything, and nothing on my console of the user logged, of course, I have running

一切都很完美,但是对于 privateChannel 我有问题 Laravel Echo 服务器没有做任何事情,并且我的用户控制台上没有任何记录,当然,我已经运行

php artisan queue:listen redis

my private channel I lunch the event in my controller

我的私人频道我在我的控制器中吃午饭

use App\Events\NewLikePostEvent;

$data = array(
     'user_id' => Hashids::encode($post->user_id),
     'user_name' => $name_user
);

event(new NewLikePostEvent($data));

In the project I have this files:

在项目中我有这个文件:

channels.php

频道.php

Broadcast::channel('like-received.{id}', function ($user, $id) {
    return true;
});

Broadcast::channel('todocanales', function ($user, $id) {
    return true;
});

bootstrap.js

引导程序.js

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: 'http://imagenes.dev:6001'
});

app.js

应用程序.js

$(document).ready(function(){

    $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
                'X-Socket-Id': Echo.socketId()
            }
    });

    var receiverId = document.getElementById('receiver_id').value;


    Echo.private('like-received.'+ receiverId).listen('NewLikePostEvent', function(e) {
        console.log("Wena!, a "+e.data.user_name + " le ha gustado uno de tus aportes");
        console.log(e);
    });


    Echo.channel('todocanales').listen('HolaEvent', function(e) {
        console.log(e);
    });

});

for the receiverId I use an input hidden in the footer

对于receiverId,我使用隐藏在页脚中的输入

<input type="hidden" id="receiver_id" value="{{Hashids::encode(Auth::user()->id)}}" />

and I have two Events

我有两个事件

NewLikePostEvent.php

NewLikePostEvent.php

<?php

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;

class NewLikePostEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $data;

    public function __construct(array $data = [])
    {
        $this->data = $data;
    }

    public function broadcastOn()
    {
        return new PrivateChannel('like-received.'.$this->data->user_id);

    }
}

HolaEvent.php

HolaEvent.php

<?php

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;

class HolaEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $data;

    public function __construct(array $data = [])
    {
        $this->data = $data;
    }

    public function broadcastOn()
    {
        return new Channel('todocanales');

    }
}

My laravel-echo-server.json

我的 laravel-echo-server.json

{
    "authHost": "http://imagenes.dev",
    "authEndpoint": "/broadcasting/auth",
    "clients": [
        {
            "appId": "ec69415ae1adcbf2",
            "key": "578712cd13fd83f7cadef22742d6728c"
        }
    ],
    "database": "redis",
    "databaseConfig": {
        "redis": {
            "host": "127.0.0.1",
            "port": "6379"
        },
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": "imagenes.dev",
    "port": "6001",
    "protocol": "http",
    "socketio": {},
    "sslCertPath": "",
    "sslKeyPath": ""
}

.env file (not all but the most important part)

.env 文件(不是全部,但最重要的部分)

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:ewoyjfyNjXd0FArdsfdsfsNLV7VQH35s=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://imagenes.dev
SOCKET_PORT=6001

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=imagenes
DB_USERNAME=root
DB_PASSWORD=secret

BROADCAST_DRIVER=redis
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_DRIVER=redis

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

and I have running this socket io script with node server.js

我已经使用 node server.js 运行了这个 socket io 脚本

server.js

服务器.js

require('dotenv').config();
const server = require('http').Server();
const io = require('socket.io')(server);
const Redis = require('ioredis');
const redis = new Redis();

server.listen({
    port: process.env.SOCKET_PORT
});

redis.subscribe('*');

console.log(process.env.SOCKET_PORT);


redis.on('like-received.*', function (channel, message) {
    const event = JSON.parse(message);
    io.emit(event.event, channel, event.data);
});

redis.on('todocanales', function (channel, message) {
    const event = JSON.parse(message);
    io.emit(event.event, channel, event.data);
});

and finally my

最后我的

BroadcastServiceProvider.php

广播服务提供者.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;

class BroadcastServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {

        Broadcast::routes(['middleware' => ['web', 'auth']]);

        require base_path('routes/channels.php');
    }
}

and when execute the event NewLikePostEvent with private channel in the console of queue's have a infinite get

并且当在队列的控制台中使用私有通道执行事件 NewLikePostEvent 时有一个无限的获取

Console Output

控制台输出

?[33m[2017-05-10 07:07:10] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:12] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:14] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:16] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:18] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:20] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:21] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:23] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:25] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:27] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:29] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:31] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:33] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:35] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:37] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:38] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:40] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:42] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:44] Processing:?[39m App\Events\NewLikePostEvent
?[33m[2017-05-10 07:07:46] Processing:?[39m App\Events\NewLikePostEvent

PS: I know the use of maxTries into the server is only a more onformation of my case the infinite cycle of event

PS:我知道使用maxTries进入服务器只是我案例无限循环事件的更多信息

I put the code because maybe can help in the future I hope someone can help me :D

我放代码是因为将来可能会有所帮助我希望有人可以帮助我:D

Regards!

问候!

采纳答案by Diego Cortés

Fixed!

固定的!

The problem of that the event is infinite processing and never was processed was because in my event I use:

该事件是无限处理并且从未被处理的问题是因为在我的事件中我使用:

public function broadcastOn()
{
    return new PrivateChannel('like-received.'.$this->data->user_id);

}

but $data is a array not object it was a typing error of me xD and the name of channel I replaced dot (.) for (-)

但是 $data 是一个数组而不是对象它是我的输入错误 xD 和通道的名称我将点 (.) 替换为 (-)

'like-received.'.$this->data->user_id

to

'like-received-'.$this->data['user_id']

finally the broadcastOn is

最后广播是

public function broadcastOn()
{
    return new PrivateChannel('like-received-'.$this->data['user_id']);

}

and the rest of code I mixed with the code repo of Parth Vora :) (thanks!) https://github.com/xparthx/laravel-realtime-chat

其余代码我与 Parth Vora 的代码仓库混合在一起 :)(谢谢!)https://github.com/xparthx/laravel-realtime-chat

and I dont needed to use server.js file for this we use Laravel echo server

我不需要为此使用 server.js 文件,我们使用 Laravel 回声服务器

and the app.js I changed to

和我改成的 app.js

window.Echo.private('like-received-'+window.Laravel.user).listen('NewLikePostEvent', function(e) {
    console.log("Wena!, a "+e.data.user_name + " le ha gustado uno de tus aportes");
    console.log(e);

});

You can see that now I use window.Laravel.user this I created on blade file

你可以看到现在我使用 window.Laravel.user 这是我在刀片文件上创建的

<script>
        window.Laravel = {
            'csrfToken': '{{ csrf_token() }}',
            'user': '{{Hashids::encode(Auth::user()->id)}}'
        };
 </script>

I hope this will be helpful to someone because I tried 3 days on fix this hahahha :D

我希望这对某人有帮助,因为我尝试了 3 天来解决这个问题哈哈哈:D

回答by Parth Vora

This problem is very hard to troubleshoot without complete source code and running app.

如果没有完整的源代码和运行的应用程序,这个问题很难解决。

So you have the issue with the private channel.

所以你有私人频道的问题。

I have implemented all 3 types of channels(private, public & presence) in this chat app, maybe you can get some ideas from it:

我已经在这个聊天应用程序中实现了所有 3 种类型的渠道(私人、公共和在线),也许你可以从中得到一些想法:

https://github.com/xparthx/laravel-realtime-chat

https://github.com/xparthx/laravel-realtime-chat

Thanks

谢谢