2

Is it possible to implement SSE on Joomla, like how it is implemented in pure PHP here?

Here is what I have so far:

administrator/components/com_component/controllers/sync.php

class ComponentControllerSync extends JControllerLegacy
    public function execute()
    {
            $close = array(
                    'id' => 'CLOSE',
                    'message' => 'stream closed');

            $progress = array(
                    'id' => 'PROGRESS',
                    'message' => '100/100 done',
                    'progress' => '100%');

            header('Content-Type: text/event-stream');
            header('Cache-Control: no-cache');
            echo "data: " . json_encode($progress) . PHP_EOL;
            echo PHP_EOL;
            ob_flush();
            flush();

            sleep(5);

            echo "data: " . json_encode($close) . PHP_EOL;
            echo PHP_EOL;
            ob_flush();
            flush();

            JFactory::getApplication()->close();
    }
}

JavaScript which calls the controller

(function($, window, document){
    $(function(){
            $('#sync').on('click', function(){
                    $.eventsource({
                            label: 'evt',
                            url: 'index.php?option=com_component&task=sync.execute',
                            dataType: 'text',
                            open: function(data) {
                                    console.log('started');
                            },
                            message: function(e) {
                                    var json = e;
                                    var id = e.id;

                                    if(id == 'PROGRESS'){
                                            console.log(json.message + json.progress);
                                    }
                                    else if(id == 'CLOSE'){
                                            console.log(json.message);
                                            $.eventsource('close', 'evt');
                                    }
                                    else if(id == 'ERROR'){
                                            console.log(json.message);
                                            $.eventsource('close', 'evt');
                                    }
                            }
                    });
            });
    });
})(window.jQuery, window, document);

Joomla takes all of the echos into a buffer then presents the output to the client, which is the opposite of what I wanted. Is there a way to go around this buffer and stream the echos?

1

By default, Joomla executes a controller and renders a page in way defined to optimize buffering in a single output. Your routine works in a different way, having control over the output and browser channel.

Besides the buffering issue, the main problem with long-running PHP scripts is web server session timeout (max_execution_time). Even if it returns periodic outputs to the browser with the detailed technique, the session can be killed if the page does complete before max_execution_time.

If you cannot define a max_execution_time or, for performance reasons, max_execution_time has to be short, it is better to break the task in asynchronic callbacks, and keep the execution time in the same order than a common page.

| improve this answer | |
  • That is certainly something to consider and I am already thinking of a way to adapt the design for async callbacks. However, this doesn't directly answer the original question, which is, is it possible to get around Joomla's default rendering behavior? – ehz350 Nov 13 '14 at 8:08
  • No, you are working inside Joomla, you have to deal with Joomla index.php and the rest of previous code executed before your controller and its context. – Anibal Nov 13 '14 at 17:08
  • Out of curiosity, at what point does Joomla start the output buffering? Would using a System plugin allow you to hook early enough in the process to avoid that? (Purely a theoretical question... not something I'm considering trying myself!) – John Rix Nov 14 '14 at 23:04
  • Yes, you could implement a system plugin to run onInit and at the end kill any further processing. – Anibal Nov 15 '14 at 18:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.