Skip to content

Loading…

configurable retry time #5

Closed
dobrys opened this Issue · 3 comments

2 participants

@dobrys

I saw in that page : http://www.html5rocks.com/en/tutorials/eventsource/basics/#toc-reconnection-timeout

that is possible to control reconnection timeout, but in your code in fallback function - it is hard-coded to 500 !
setTimeout(
function () {
pluginFns._private.openPollingSource.call( this, options );
},
// matches speed of host api EventSource
500
);

When I try it in Chrome - that use Native EventSource and set in php file immediately after content type

header("Content-Type: text/event-stream\n\n");
echo "retry: 10000\n";
//set reconnection-timeout to 10sec.
echo 'data: ' . json_encode(
                  array(
                    0 => array(
                      'time' => time(),
                      'message' => 'Some kind of foo'
                    ),
                    1 => array(
                      'time' => time(),
                      'message' => 'Some kind of quux'
                    )
                  )
                ) . "\n";

Chrome try to reconnect exactly after 10 sec.
But Firefox - that use fallback - not.

Also , depending to W3C specifications there are other fields that can be sent from server
http://dev.w3.org/html5/eventsource/#processField

your code seems to parse only DATA field and probably "last event ID" (no test it)
but when i set "retry" field (before data field) - parsing of DATA seems to goes wrong - it messes with "retry" field.

I make some changes to test setting retry time
(see code marked by //DOBRYS)


//--------------------------------------------
// open fallback event source

openPollingSource: function ( options ) {
                var rec_timeout = 400;//DOBRYS
                var label = options.label, 
                    source;
                if ( stream.cache[label] ) {

                    source = jQuery.ajax({
                        type: "GET",
                        url: options.url,
                        data: options.data,
                        beforeSend: function () {
                            if ( stream.cache[label] ) {
                                this.label = label;
                                stream.cache[label].options.open.call( this );
                            }
                        },
                        success: function ( data ) {

                            var tempdata,
                                label = options.label,
                                parsedData = [],
                                streamData = jQuery.map( data.split("\n"), function(sdata, i) {
                                    return !!sdata && sdata;
                                }), 
                                idx = 0, length = streamData.length;

                            if ( jQuery.isArray(streamData) ) {
                                console.log('???');
                                console.log(streamData)
//something in that loop mess code formating in issue field 
//so, will replace loop with dummy val..
                                for (idx loop) {

                                    if ( streamData[idx] ) {
                                        tempdata = streamData[idx].split("data: ")[1];
                                        //DOBRYS
                                        if(streamData[idx].split("retry: ")[1]){
                                            rec_timeout = streamData[idx].split("retry: ")[1];//DOBRYS
                                        }//eof DOBRYS                                        
                                        // Convert `dataType` here
                                        if ( options.dataType === "json" ) {
                                            tempdata = jQuery.parseJSON( tempdata );
                                        }
                                        parsedData[ parsedData.length ] = tempdata;
                                    }
                                }
                            }

                            if ( stream.cache[label] ) {
                                this.label = label;
                                stream.cache[label].lastEventId++;
                                stream.cache[label].history[stream.cache[label].lastEventId] = parsedData;
                                stream.cache[label].options.message.call(this, parsedData[0] ? parsedData[0] : null, {
                                    data: parsedData,
                                    lastEventId: stream.cache[label].lastEventId
                                });
                                console.log('rec_timeout: ' + rec_timeout);//DOBRYS
                                var reconnect_time_out = rec_timeout ? rec_timeout : 500;//DOBRYS
                                    console.log('reconnect_time_out:' + reconnect_time_out);//DOBRYS
                                setTimeout(
                                    function () {
                                        pluginFns._private.openPollingSource.call( this, options );
                                    },
                                    // matches speed of host api EventSource
                                    reconnect_time_out
                                );
                            }
                        },
                        cache: false,
                        timeout: 50000
                    });
                }
                return source;
            }

//--------------------------------------------

With these changes - reconnect timeout seems to work.
But "data" in message: function(data) { ....
is NULL

Think that is from adding "retry" field before data field (in php file)

@rwaldron
Owner

Awesome! Thanks for such a thorough explanation :)

@dobrys

np.
;-)

@dobrys

My suggestion for parsing and processing (using Retry Time)

// open fallback event source
openPollingSource: function (options) {
    var rec_timeout = 5000; //DOBRYS
    var label = options.label,
        source;
    if (stream.cache[label]) {
        source = jQuery.ajax({
            type: "GET",
            url: options.url,
            data: options.data,
            beforeSend: function () {
                if (stream.cache[label]) {
                    this.label = label;
                    stream.cache[label].options.open.call(this);
                }
            },
            success: function (data) {
                var tempdata, label = options.label,
                    parsedData = [],
                    pData = [],
                    streamData = jQuery.map(data.split("\n"), function (sdata, i) {
                        return !!sdata && sdata;
                    }),
                    idx = 0,
                    length = streamData.length;
                if (jQuery.isArray(streamData)) {
                    newData = jQuery.map(streamData, function (elem, index) {
                        var eData = {};
                        if (typeof elem == 'string') {
                            if (elem.indexOf(':') > 0) {
                                arr = elem.split(': ');
                                //console.log(arr);
                                eData[arr[0]] = arr[1];
                                return eData
                            }
                        }
                    })
                    //console.log('newData');
                    //console.log(newData);
                    jQuery(newData).each(function (i, el) {
                        //console.log('el');
                        //console.log(el)
                        // console.log(typeof el)
                        //console.log(el.data)
                        //console.log(el.retry)
                        if (el.retry) {
                            rec_timeout = el.retry;
                        }
                        if (el.data) {
                            // Convert `dataType` here
                            if (options.dataType === "json") {
                                tempdata = jQuery.parseJSON(el.data);
                            } else {
                                tempdata = el.data;
                            }
                            //console.log('tempdata ???');
                            //console.log(tempdata)
                            parsedData[parsedData.length] = tempdata;
                        }
                    }) //eof each
                    //console.log('parsedData ??? After loop');
                    //console.log(parsedData)
                }
                if (stream.cache[label]) {
                    //console.log(stream.cache[label])
                    this.label = label;
                    stream.cache[label].lastEventId++;
                    stream.cache[label].history[stream.cache[label].lastEventId] = parsedData;
                    //stream.cache[label].options.message.call(this, parsedData[0] ? parsedData[0] : null, {
                    stream.cache[label].options.message.call(this, parsedData ? parsedData : null, {
                        data: parsedData,
                        lastEventId: stream.cache[label].lastEventId
                    });
                    console.log('rec_timeout: ' + rec_timeout); //DOBRYS
                    //var reconnect_time_out = rec_timeout ? rec_timeout : 35000;//DOBRYS
                    var reconnect_time_out = 5000;
                    if (rec_timeout) {
                        reconnect_time_out = rec_timeout
                    }
                    console.log('reconnect_time_out:' + reconnect_time_out); //DOBRYS
                    setTimeout(

                    function () {
                        pluginFns._private.openPollingSource.call(this, options);
                    },
                    // matches speed of host api EventSource
                    reconnect_time_out);
                }
            },
            cache: false,
            timeout: 50000
        });
    }
    return source;
}

I test it and seems to work.
Please test it also.
Especially

if (stream.cache[label]) { ....

I change only to return entire array - not only first row

stream.cache[label].options.message.call(this, parsedData ? parsedData : null, {....

@rwaldron rwaldron closed this in 5743baf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.