Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HOW TO: Get real-time notifications in Laravel 4 using Iron.io MQ, Push Queues & AJAX

I've integrated ironMQ push queues in my Laravel 4 app for longer running processes. I have some views that perform a $.get that might take 30 seconds. I wanted to see what others are doing to easily get notified when ironMQ is done pushing back to an endpoint.

An example of what I will be doing with push queues mostly:

public function getCompletedTasks() {

    $user = User::find(Auth::user()->id);

    Queue::push(function($job) use ($user) {
        $recent = new Recent;
        $tasks  = $recent->getCompletedTasks($user);
        // append data from $tasks to DOM
        // here's where I want to receive my notification
    });     
}

Here I am just getting tasks from an API that match data from user.

I know I can store the response data to a database and use AJAX long polling to constantly check for the data but it seems like too much work for most situations I will need to do this. I don't know much about websockets. What types of things have you guys done in these situations? And if you have any examples that would be very helpful. Thanks.

UPDATE: Solved the issue using Pusher. See my answer.

like image 689
Jared Eitnier Avatar asked Dec 19 '22 21:12

Jared Eitnier


1 Answers

I was able to solve my problem with the help of Pusher. Here's what I did:

Setup my Iron MQ push queue as normal. In routes.php:

Route::post('queue/push', function() {
    return Queue::marshal();
});

Installed pusher laravel package.

In my controller then I Queue::push my data. Inside the closure I trigger a new Pusher channel. This will obviously only trigger when the data has been returned from IronMQ.

public function getCompletedTasks() {

    $user = User::find(Auth::user()->id);

    Queue::push(function($job) use ($user) {

        $recent = new Recent;
        $tasks  = $recent->getCompletedTasks($user);

        $pusher = new Pusher('xxx', 'xxx', 'xxx');
        $pusher->trigger('reports', 'get_completed_tasks', array('tasks' => $tasks));

        $job->delete();
    });
});

Next in my view I call my AJAX function with no callback since I won't be doing anything else just yet:

$.get('account/tasks/completed');

Next in my view I initialize Pusher, subscribe to the event and bind get_completed_tasks to the Pusher channel. Now we just wait for a response from Pusher which will then allow me to perform the latter part of my original AJAX request:

{{ HTML::script('//js.pusher.com/2.1/pusher.min.js') }}
<script>
var pusher  = new Pusher('xxx');
var channel = pusher.subscribe('reports');
    channel.bind('get_completed_tasks', function(data) {
        // do something with the data returned
    });
</script>

Once I used Pusher in my app, the rest was a breeze. Hope this helps someone!

like image 89
Jared Eitnier Avatar answered May 07 '23 08:05

Jared Eitnier