4

My problem is basically the following: I have a webpage running an online radio on another subdomain (Airtime sourcefabric). Now I figured out that this radio plugin has a nice real-time API, so I can access the prevoius, the current, and the next track (and show) infos in JSON from this URL: http://music.wickedradionet.com/api/live-info .

I need to show these infos on the webpage. I can make it work with a javascript interval, updating the infos from the API URL every second (or every 5 second, doesn't matter), but I think there must be a better way doing this.

Is there any way to check if the file was changed, and update the infos only if they aren't the same? I think it can be done with some tricky PHP like setting up a CRON job, or maybe with a WebSocket thing. Any better way than checking it in a JS interval?

The javascript I use now for updating: http://wickedradionet.com/js/wickedradio-playlist.js

Cœur
  • 37,241
  • 25
  • 195
  • 267
Balázs Varga
  • 1,797
  • 2
  • 16
  • 32
  • You might want to look into push notifications and long polling – STT LCU Apr 24 '15 at 06:49
  • Can you please share a good (and free) PHP class for this? Or tell me a bit more about how can I do this? I've heard about push notifications but never used them before... – Balázs Varga Apr 24 '15 at 06:56
  • Here an answer about long polling [link](http://stackoverflow.com/questions/333664/how-to-implement-basic-long-polling). On client side use Websocket. – emaniacs Apr 24 '15 at 07:09
  • Thanks, I'll check them out. Hope i can find a not-too-complex solution. :) – Balázs Varga Apr 24 '15 at 07:12
  • There is really no need to set timeout every few seconds. In time when current show finishes then request new data - it is simple as that. – skobaljic Apr 24 '15 at 07:22

2 Answers2

4

Below describes two ways on how you can improve your polling:

1) More efficient AJAX Polling

Instead of constantly performing an ajax request every second (whether or not you get the data), you can create a hacky open connection with the server to poll once the request is completed as shown below. The important part of the $.ajax() call is the complete option. The timeout (i.e. 30 seconds) is to make sure the polling continues if the cycle ever breaks.

(function betterPoll(){
    $.ajax({ url: 'http://music.wickedradionet.com/api/live-info/', success: function (data) {
        // do something with "data"
    }, dataType: "json", complete: betterPoll, timeout: 30000 });
})();

2) WebSocket Connection

An even better alternative is WebSocket. This allows for a full-duplex, low-latency connection to stay open between the client and server, enabling "real time" communication.

If you're using Node.js, the docs provide examples on how you can use Socket.IO for WebSocket communication. If you're using PHP, a quick search led me to Ratchet and PHP WebSockets.

Below is an example using Socket.IO:

In your HTML:

<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script src="example.js"></script>

In "example.js", you can have something like this:

var socket = io.connect('http://music.wickedradionet.com/api/live-info/');
socket.on('an event', function (data) {
  // do something with "data"
  socket.emit('another event', { other: 'data' });
});

On the server, you would do something similar using .on('another event', function () {}) and .emit('an event', function () {}).

boombox
  • 2,396
  • 2
  • 11
  • 15
  • Thanks for your deatailed answer! It seems that I need to dig into this WebSocket thing a bit deeper. :) Another question: In your second answer, you provide a node.js server side code. Can I use it on an Apache(PHP) server? – Balázs Varga Apr 24 '15 at 07:22
  • The websocket example I showed in my answer is actually in "example.js" on your client. Visit the docs to see how you can do this on the server via node.js. For an Apache PHP server, you can try out this: http://socketo.me/ instead of socket.io. – boombox Apr 24 '15 at 07:28
  • Thanks, I'll try it out as soon as possible! :) I need to re-develop the whole website, that's why I need a better solution than the current one. – Balázs Varga Apr 24 '15 at 07:31
  • It seems that you get the time that the current song ends from the API. So an alternative in this specific case might be polling just around the time that the current song ends. – CompuChip Apr 24 '15 at 07:37
  • One issue with performing the poll around the calculated time the file will change is that if a track is ever skipped or a delay occurs on their end for whatever reason in between the ajax requests, this could mess with the accuracy. – boombox Apr 24 '15 at 09:14
1

You have exact time when the file will change, it is the time when next song starts. All you need to do is to calculate time difference to schedule new request.

function stringToDate(s)  {
 s = s.split(/[-: ]/);
 return new Date(s[0], s[1]-1, s[2], s[3], s[4], s[5]*1);
};
function getPlaylistData() {
 $.ajax({
  dataType: "jsonp",
  url: "http://music.wickedradionet.com/api/live-info/",
  success: function (result) {
   /* Change your DOM, than calculate time for next request this way: */
   var requestTime = stringToDate( result.schedulerTime ).getTime() - result.timezoneOffset*1000;
   var nextChange = stringToDate( result.next.starts ).getTime();
   var differenceInMiliseconds = nextChange-requestTime;
   console.log( differenceInMiliseconds );
   setTimeout(getPlaylistData, differenceInMiliseconds);
  }
 });
};
$(document).on('ready', function () {
    getPlaylistData();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
skobaljic
  • 9,379
  • 1
  • 25
  • 51
  • It's not an universal solution, but works well in this case. Thanks for your answer too, maybe i'll use it here, because it's simple and works! :) – Balázs Varga Apr 24 '15 at 08:25