带有私有通道的 Laravel Echo SocketIO
Posted
技术标签:
【中文标题】带有私有通道的 Laravel Echo SocketIO【英文标题】:Laravel Echo SocketIO with private channel 【发布时间】:2017-10-09 11:04:44 【问题描述】:大家好,我在没有 Vue 的情况下使用 Laravel Echo 和 SocketIO,只有 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';
);
在我的 laravel echo 服务器控制台中显示:
[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
在浏览器控制台中,我得到了
~~~ 对象数据:对象,套接字:空 ~~~
一切都很完美,但是使用 privateChannel 我有问题 Laravel Echo 服务器没有做任何事情,我的用户控制台上也没有任何记录,当然,我正在运行
php artisan queue:listen redis
我的私人频道我在我的控制器中为活动提供午餐
use App\Events\NewLikePostEvent;
$data = array(
'user_id' => Hashids::encode($post->user_id),
'user_name' => $name_user
);
event(new NewLikePostEvent($data));
在项目中我有这个文件:
channels.php
Broadcast::channel('like-received.id', function ($user, $id)
return true;
);
Broadcast::channel('todocanales', function ($user, $id)
return true;
);
bootstrap.js
import Echo from "laravel-echo"
window.Echo = new Echo(
broadcaster: 'socket.io',
host: 'http://imagenes.dev:6001'
);
app.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);
);
);
对于receiverId,我使用隐藏在页脚中的输入
<input type="hidden" id="receiver_id" value="Hashids::encode(Auth::user()->id)" />
我有两个事件
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
<?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');
我的 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 文件(不是全部,但最重要的部分)
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
我已经用 node server.js 运行了这个 socket io 脚本
server.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);
);
最后是我的
BroadcastServiceProvider.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');
并且在队列的控制台中使用私有通道执行事件 NewLikePostEvent 时获得无限次
控制台输出
?[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:我知道在服务器中使用 maxTries 只是我的案例无限循环事件的更多信息
我放代码是因为将来可能会有所帮助我希望有人可以帮助我:D
问候!
【问题讨论】:
您的问题很好地回答了我的问题。竖起大拇指 对不起,我知道这是旧的。但分享您的APP_KEY=
或其他凭据可能不是一个好习惯。即使对于本地环境,我也会避免它。
【参考方案1】:
已修复!
事件是无限处理并且从未被处理的问题是因为在我的事件中我使用:
public function broadcastOn()
return new PrivateChannel('like-received.'.$this->data->user_id);
但是 $data 是一个数组而不是对象它是我的输入错误 xD 和通道的名称我将点 (.) 替换为 (-)
'like-received.'.$this->data->user_id
到
'like-received-'.$this->data['user_id']
broadcastOn 终于是
public function broadcastOn()
return new PrivateChannel('like-received-'.$this->data['user_id']);
以及我与 Parth Vora 的代码仓库混合的其余代码 :)(谢谢!)https://github.com/xparthx/laravel-realtime-chat
我不需要使用 server.js 文件,我们使用 Laravel 回显服务器
和我改成的 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);
);
你可以看到现在我使用了我在刀片文件上创建的 window.Laravel.user
<script>
window.Laravel =
'csrfToken': ' csrf_token() ',
'user': 'Hashids::encode(Auth::user()->id)'
;
</script>
我希望这对某人有所帮助,因为我尝试了 3 天来解决这个问题哈哈哈:D
【讨论】:
【参考方案2】:如果没有完整的源代码和正在运行的应用程序,这个问题很难解决。
所以你有私人频道的问题。
我已经在这个聊天应用中实现了所有 3 种类型的频道(私人、公共和在线),也许你可以从中得到一些想法:
https://github.com/xparthx/laravel-realtime-chat
谢谢
【讨论】:
非常感谢!我可以用你的示例代码修复,这个工作我混合了我的代码和你的代码哈哈哈,在我的代码中我有一个事件错误,我使用了 $this->data->user_id 但 $data 是一个数组,所以我需要使用$this->data['user_id'] 这是一个输入错误,现在事件已处理:D以上是关于带有私有通道的 Laravel Echo SocketIO的主要内容,如果未能解决你的问题,请参考以下文章
laravel-echo-server 404 尝试进行身份验证时
Nuxtjs + Laravel Echo + Laravel Passport + Laravel WebSockets 无法从私人/状态通道获取事件