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
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:
[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
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:
Broadcast::channel('like-received.{id}', function ($user, $id) {
return true;
});
Broadcast::channel('todocanales', function ($user, $id) {
return true;
});
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'socket.io',
host: 'http://imagenes.dev:6001'
});
$(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
<input type="hidden" id="receiver_id" value="{{Hashids::encode(Auth::user()->id)}}" />
and I have two Events
<?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);
}
}
<?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');
}
}
{
"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": ""
}
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
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
<?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
?[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
I put the code because maybe can help in the future I hope someone can help me :D
Regards!
Private channels require you to authorize that the currently authenticated user can actually listen on the channel. This is accomplished by making an HTTP request to your Laravel application with the channel name and allowing your application to determine if the user can listen on that channel.
Web socket and Socket.IO in particular make it possible. But Laravel from it side doesn't have direct support for http socket, so we have to implement a little NodeJS Socket.IO server and make possible to push message to it from the Laravel backend.
Pusher Channels acts as a realtime layer between your client and server events, maintaining persistent connections to the clients.
Socket servers usually were not that easy to setup, but Laravel Echo Server changes this. This is completely free, you only have to run the socket server yourself.
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 (-)
'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
and I dont needed to use server.js file for this we use Laravel echo server
and the app.js I changed to
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
<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
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:
https://github.com/xparthx/laravel-realtime-chat
Thanks
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With