Home » Nodejs » Laravel Broadcast with Redis not working/connecting?

Laravel Broadcast with Redis not working/connecting?

Posted by: admin November 30, 2017 Leave a comment

Questions:

So I’m trying to broadcast Laravel 5 Events with the help of Redis. No I don’t wanna use a service like Pusher since it’s not free (even if the free limit would be enough for me) and I wanna keep control of the broadcast server.

So what I’ve done so far is, I’Ve set up a redis server (listening on port 6379 -> default), I’ve set up the following event:

class MyEventNameHere extends Event implements ShouldBroadcast
{
    use SerializesModels;
    public $data;

    /**
     * Create a new event instance.
     *
     * @return \App\Events\MyEventNameHere
     */
    public function __construct()
    {
        $this->data = [
            'power' => 10
        ];
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return ['pmessage'];
    }
}

I registered a route to that event:

Route::get('test',function()
{
    event(new App\Events\MyEventNameHere());
    return "event fired";
});

I’ve created (more like copied :P) the node socket server:

var app = require('http').createServer(handler);
var io = require('socket.io')(app, {origins:'*:*'});

var Redis = require('ioredis');
var redis = new Redis();

app.listen(6379, function() {
    console.log('Server is running!');
});

function handler(req, res) {
    res.writeHead(200);
    res.end('');
}

io.on('connection', function(socket) {
    console.log(socket);
});

redis.psubscribe('*', function(err, count) {
});

redis.on('pmessage', function(subscribed, channel, message) {
    console.log(message);
    message = JSON.parse(message);
    io.emit(channel + ':' + message.event, message.data);
});

And I created the view to actually receive the broadcast (testview.blade.php):

@extends('layout')
@section('content')
<p id="power">0</p>

<script>
var socket = io('http://localhost:6379');
socket.on("pmessage:App\Events\MyEventNameHere", function(message) {
    console.log(message);
    $('#power').text(message.data);
});
console.log(socket.connected);
</script>
@endsection

I can launch the redis server without any problems.
I can launch the node socket.js server and I’m getting the response “Server running”

When I hit the route to the event I get the return “event fired” in my browser.

When I hit the route to the actual view

Route::get('test/view',function()
{
    return view('testview');
});

I can see the whole page (layout is rendered), and the webconsole does not show any errors.

However if I fire the event, the view won’t change, which means, the broadcast is not received right?

Now I included an output for the console

console.log(socket.connected);

which should show me if the client is connected to the socket.io right?

Well, the output says false. What am I doing wrong here?

Further information on my setup: I’m running the whole project on the php built-in server, the whole thing is running on Windows (if ever that could matter), my firewall is not blocking any of the ports.

EDIT 1:

I forgot to say that my node server is not receiving the messages as well… It only says “Server running”, nothing else.

EDIT 2:

I used another socket.js:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();

app.get('/', function(req, res) {
    res.sendFile(__dirname + '/index.html');
});

redis.subscribe('test-channel', function () {
    console.log('Redis: test-channel subscribed');
});

redis.on('message', function(channel, message) {
    console.log('Redis: Message on ' + channel + ' received!');
    console.log(message);
    message = JSON.parse(message);
    io.emit(channel, message.payload)
});

io.on('connection', function(socket) {
    console.log('a user connected');
    socket.on('disconnect', function() {
        console.log('user disconnected');
    });
});

http.listen(3000, function() {
    console.log('listening on *:3000');
});

And this time the console receives the messages.
So if the node socket.io receives the messages, then what’s wrong with my client? Obviously the messages are being broadcasted correctly, the only thing is that they are not being received by the client…

Answers:

I can’t say what is exactly wrong and probably no one can’t, because your problem is to broad and enviroment dependent. Using Wireshark Sniffer you can easily determinate part of solution that is not working correctly and then try find solution around actual problem.

If your question is about how to do that, I will suggest not involving node on server side and use .NET or Java language.

Questions:
Answers:

The problem with your code is you are connecting your client socket to the redis default port 6379 rather than the node port that is 3000.

So in your blade view change var socket = io(‘http://localhost:6379‘); to var socket = io(‘http://localhost:3000‘);

Questions:
Answers:

have you tried to listen to the laravel queue, from command line, before to fire the event?


php artisan queue:listen