Laravel 4 and NodeJs/Redis pub/sub realtime notifications

Currently I am building an application where we can fill in live scores and I needed something to update all my visitors whenever a score has been updated by one of the admins.

Whenever an admin updates the score via the Laravel 4 backend I fire an event and publish it to Redis. I’ve setup a simple NodeJS server which listens to Redis for incoming changes. NodeJS will redirect the message to all Socket.IO clients.


1. Open config//database.php
2. Configure:

'redis' => array(

		'cluster' => false, //publish won't work when set to true

		'default' => array(
			'host'     => '',
			'port'     => 6379,
			'database' => 0,


3. Create app\events folder and update composer.json

"autoload": {
	"classmap": [

4. Create UpdateScoreEventHandler.php in the events folder:

class UpdateScoreEventHandler {

    CONST EVENT = 'score.update';
    CONST CHANNEL = 'score.update';

    public function handle($data)
        $redis = Redis::connection();
        $redis->publish(self::CHANNEL, $data);

5.Create listeners.php (next to routes.php/filters.php):

Event::listen(UpdateScoreEventHandler::EVENT, 'UpdateScoreEventHandler');

6. Add to start/global.php:

require app_path().'/listeners.php';

7. Fire event in controller (update score) :

Event::fire(UpdateScoreEventHandler::EVENT, array($updatedMatch));

8. Run composer update (class loading)


1. Download NodeJS via the website (
2. Create a nodejs folder in Laravel’s root.
3. /nodejs/npm install express redis
4. Create nodejs server (e.g. server.js) and store it /nodejs

var express =   require('express'),
    http =      require('http'),
    server =    http.createServer(app);

var app = express();

const redis =   require('redis');
const io =      require('');
const client =  redis.createClient();

server.listen(3000, 'localhost');

io.listen(server).on('connection', function(client) {
    const redisClient = redis.createClient()

    redisClient.on("message", function(channel, message) {
        //Channel is e.g 'score.update'
        client.emit(channel, message);

    client.on('disconnect', function() {


1. Include client in your page (
2. Add code below to receive messages when a score has been updated.

<script type="text/javascript">// <![CDATA[
            var socket = io.connect('');

            //socket.on('connect', function(data){
            //    socket.emit('subscribe', {channel:'score.update'});

            socket.on('score.update', function (data) {
                //Do something with data
                console.log('Score updated: ', data);

// ]]></script>

5. Start the server

/nodejs/node server.js


1. Download Redis (
2. Go to extacted folder
3. Go to src folder
4. Start the server


Optional – Monitor Redis (requests)

1. ./redis-cli monitor

43 comments to Laravel 4 and NodeJs/Redis pub/sub realtime notifications

  • MarkL

    Good tutorial. You should have gone with SockJS, which is bounds better than SocketIO.

  • Why is it better?

    Will look into it. Thanks for your comment!

  • will

    I am unable to get your example to work. it seems that is not serving the client js? I managed to find a cdn hosting it but now my client cannot connect to the socket server

  • When you start the server do you see ‘info – started’ in your console?

    Did you download and added the javascript file to your page?

  • Robert Klep

    Instead of creating a separate Redis client for each incoming connection, you can create just one and use io.sockets.emit() to broadcast the message to all clients.

  • Hi Robert,

    This works as well but not with io.sockets.emit(). Is this what you mean?

    var express =   require('express'),
        http =      require('http'),
        server =    http.createServer(app);
    var app = express();
    const redis =   require('redis');
    const io =      require('');
    const redisClient = redis.createClient()
        .set('log level', 1) //1 = warn
        .on('connection', function(client) {
                redisClient.on("message", function(channel, message) {
                    //Channel is e.g 'score.update'
                    client.emit(channel, message);
                client.on('disconnect', function() {
  • Robert Klep

    I was thinking more like this:

    const io = require('').listen(1338);
    const redis = require('redis');
    const redisClient = redis.createClient();


    redisClient.on('message', function(channel, message) {
    io.sockets.emit(channel, message);

  • It does work! Thanks. Is your approach better?

  • Robert Klep

    It just leaves out some code that isn’t strictly necessary :-)

  • themarko

    This is great! Never used nodejs nor redis. Does anyone know any basic resources to learn these?

  • Hi,

    Very useful information for pushing notification on real time with redis and
    But how it is going to work if we use Redis Store instead of memory store for the server side code, i m stuck in that.

  • Why use Redis at all in this case? Why not just let node.js receive published events directly via HTTP?

  • Colin,

    If you have multiple node instances running, you’ll need a common ground such as redis in order for everything to be in sync.


  • Mark, there is going to be no benefit to having multiple node instances running when Redis itself is single-threaded. So unless you also *need* multiple Redis instances, I maintain that Redis is mostly a useless additional point of failure in this particular use-case. Even then, you could quite easily have node instances which subscribe to events from the master node server and re-publish all received events. I won’t bother to test, but I’d bet that a node-only cluster would scale just as well as a node+Redis cluster and with less maintenance.

    I suppose it comes down to if you prefer Redis as your protocol for publishing events versus HTTP..

  • Colin, if you have multiple *node* instances, then you have multiple people connecting to different instances of node. If you have a pub/sub implementation, subscribers of one node instance won’t hear publishing from the other node instances, and vice versa. Therefore you need something like redis as a common ground so that those pub/subs will be in sync. Also, if you need to reboot a node instance or if it fails for one reason or another, the data in those instances are no more. Definitely not useless in a pub/sub scenario.

  • Colin

    My suggestion if you really needed to scale past one instance was “Even then, you could quite easily have node instances which subscribe to events from the master node server and re-publish all received events.”

    That is, there is no reason that you can’t have a node instance acting as both a server and a client/slave to a master instance with literally only a few extra lines of code. With pub/sub there is no persistent data so rebooting is moot, only availability matters and in my experience Redis is no more stable than Node. Using Redis+Node means two points of failure and two systems to install/configure/update where the job can be done with only one.

    I recently implemented a very similar pub/sub server and opted to do it with pure Node. To each his own.. :)

  • Ah, I think you hit it on the nail. Maybe your pub/sub doesn’t persist data, but mine definitely does :) No chat room app here… if I weren’t persisting data I would agree, no reason for redis/memcached.

  • Ah I think I was misunderstood. I’m actually using nodes pubsub with a redis connection (for the multiple instance availability) since I’m using redis for other stuff. It was far easier to use nodes pubsub vs redis pubsub even though I have access to it, but using the redis conn to share between instances makes it a no-config setup since I’m using redis for other data storing.

  • Joel

    Hello I am new to node.js. I am having some trouble getting this to work. I get this error when I try to start the server.js server

    Joels-iMac:nodejs joelcox$ node server.js
    info – started

    throw er; // Unhandled ‘error’ event
    Error: Redis connection to failed – connect ECONNREFUSED
    at RedisClient.on_error (/Applications/MAMP/htdocs/work2/nodejs/node_modules/redis/index.js:185:24)
    at Socket. (/Applications/MAMP/htdocs/work2/nodejs/node_modules/redis/index.js:95:14)
    at Socket.EventEmitter.emit (events.js:95:17)
    at net.js:441:14
    at process._tickCallback (node.js:415:13)

  • It is trying to connect to redis but the connection was refused

  • Pablo Acuña

    Hi!, very cool tutorial, works like a charm.

    I’m new on this websocket thing. It’s possible to adapt this setup to make notifications only for an specific user and the other users not be able to see the information? or for example one user to other user?

  • Probably it can but I don’t have a clue how to get it really secure.

  • Pablo

    What I did was create a channel for every user that connects to the application and use a stored secret hash for the name of the channel that is re-generated in every login. Then the notifications are send to this pseudo-private channel. I don’t know if it’s the most secure way but I can’t think in some dangerous scenario.

  • Joel

    I love this It works great. I implemented this in two of my apps. However, I Honestly Consider checking out Angular.js with Firebase.js for the front end of your app. Or use it only for the live content you want to load… like a chat or notifications. It will only take you 15 lines of code.

  • Nice tutorial. But not sure how to use it with redisStore, I’m getting the subscription multiple times!

  • Maybe because I am new to NodeJS and Redis. At some point I am not sure where to put your code. Under the paragraph Laravel, point 7.

    7. Fire event in controller (update score) :
    Event::fire(UpdateScoreEventHandler::EVENT, array($updatedMatch));

    Do I need to put it in a method inside of a desired controller class e.g. ‘UserController@indexPage’?

    Under the paragraph NodeJS, point 3.

    3. /nodejs/npm install express redis

    I don’t know how to deal with it. Please explain me a bit more. Thank you!

  • 1. Just put the Event:fire in the method which handles the save/update.
    2. It is just how node works. There is a lot of documentation on the internet.

  • Guilherme Solinscki

    Great tutorial, Stefanovich!

    It worked like a charm! Thanks

  • George

    Excellent! Thanks for sharing your knowledge! Works like a charm!!

  • George

    Could you also use psubscribe for patterns, i have tried this but seems not to work?

  • Amr

    Hi ,
    When I started the node server , its just hanging on , no messages says started , is that normal behaviour , I am using the latest version
    and by the way nothing happens when I fire the event in my controller
    any help will be appreciated

  • Great tutorial. Thank you for sharing.

    I am over most of the humps, I successfully have node/express/npm/redis and socket installed and node server working with confirmation that is up.

    When I include the file do I need to specifiy the port 3000?

    I am working local on ubuntu, using a virtual host like so:

    I tried including the a few different way. I keep getting require is not defined.

    Do I need to use require.js, or add the port number to the virtual host?

    Trying to get a grasp on this, excited to get it up and running.

    Any help is much appreciated.

  • Update, I have the client side working, but now I am getting CORS errors. I am using virtual host for my local. It is which point to /var/www/project/public

    I’m using V 0.9.*
    Express Version Latest

    I tried adding this to server.js, it is not working:

    app.use(function(req, res, next) {
    res.setHeader(‘Access-Control-Allow-Methods’, ‘GET, POST, OPTIONS, PUT, PATCH, DELETE’);
    res.setHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With,content-type’);

    server.listen(3000, ‘’);

    The node server in console is repeating this message:

    info – unhandled url

    Anyone have a solution? Thanks!

  • Simon

    This is a fantastic example, I was hoping you could offer some advice, what happens if you want to have multiple channels? What I mean is that if I have a channel called ‘project.update’ and change the name of a project and fire the event, then all the projects will be updated to have the same name. Is there away to have either multiple channels, or multiple node instances?

  • abdelwahed mohamed

    hello stefanovich i really like your article but i have a use case where i have to make the channel name dynamic like so


    and i want to ask how can i get the user_id of the current authenticated user into my laravel project from the nodejs server ?

  • wyclif

    Great tutorial, i am a newbie and i am trying to create a realtime notification system in laravel as part of my app, i am still following along with this tutorial but my question is after i have done all this on localhost how do i deploy it to a vps or a dedicated server?

  • Hi, are there any resources reasons (hardware cpu and memory) in using laravel-nodejs-redis vs laravel-ratchet-reactphp ?

    The other tutorial is here:


  • Also vs ajax long polling? (agayn, resources wise)

  • sarmishta

    Why to use redis with socket.oo and laravel?

  • Cássio

    is returning the message:
    io is not defined

    what do I do?

  • Probably you forgot:
    const io = require(‘’);

  • wycliffe

    anybody else experiencing this bug where this is firing the notifications twice?

  • john

    hi guys, im using lumen 5.2 and im trying to do this example but its not working.On listeners.php im getting this error “Class UpdateScoreEventHandler not found” can you guys help me?

Leave a Reply




You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>