Bug Not getting responses to all JSON-RPC messages sent: bug or feature?
#1
Hi there.

I'm developing a web interface to Kodi, which will display and control playlists, and is still on an early stage of development.

I'm trying to show on my page all the tracks currently on the playlist, which I get calling "Playlist.GetItems". I then receive a response with, in my current  case, some 11 songs. Communication is done through websockets.

I then wish to know the song artists. I simply iterate the playlist and send a "AudioLibrary.GetSongDetails" message with each song's songid. 

The problem is that I do nor get all the responses... Sometimes I get 8, sometimes 11 responses, and thus my playlist is not fully updated.

Could this be a problem with the JSON-RPC server? Am I sending too much messages at the same time and thus flood the system? Should I send a message only after receiving the response to the previous one? Or could this possibly be a bug?

Thanks and best regards, Luís
Reply
#2
To best describe the situation: I'm running an apache server on the same linux machine where kodi (v 16.1) is running... A bit outdated... I will try this on a more recent Installation to see if it works...

Luís
Reply
#3
Without seeing the code, that sounds like an async problem. Do you have a repo or code snippet?
Reply
#4
Hi there. Here's a stripped version of the code... Hope it helps, hope it still works, after all the code I deleted...

javascript:
 const address="localhost",
     port=9090; 
 var ws = new WebSocket('ws://'+address+':'+port+'/jsonrpc');
 var playlistItems;
 // Upon start
 ws.onopen = function(event) {
    
     send_message("Playlist.GetItems", {
         "playlistid": 0
     });
 }

 ws.onmessage = function(event) {
     var j = JSON.parse(event.data);
     if (j.id) { // response  
            switch (j.id) {
                case "Playlist.GetItems":
                     //    update playlist
                     addPlaylistData(j.result.items);
                     break;
                 case "songDetails":  
                     updateSongDetails(j.result);
                     break;
                 default:
                     alert("Unexpected response:" + alert(JSON.stringify(j)));
             }
     }
 }

function updateSongDetails(result) {
    console.log("Updating song:"+"namePerformer"+result.songdetails.songid);//    JSON.stringify(result));
    var artistNameHeader=document.getElementById("namePerformer"+result.songdetails.songid);
    artistNameHeader.innerHTML=result.songdetails.albumartist[0]+" - "+result.songdetails.album;
}

 function addPlaylistData(jsonData) {
     // function adapted from https://www.encodedna.com/javascript/pop...script.htm 
     // EXTRACT VALUE FOR HTML HEADER.     
     var col = [];
     for (var i = 0; i < jsonData.length; i++) {
         for (var key in jsonData[i]) {
             if (col.indexOf(key) === -1) {
                 col.push(key);
             }
         }
     }

     // clear current playlist
    var table=document.getElementById("music-box");     
    table.innerHTML="";
     
     // ADD JSON DATA TO THE TABLE AS ROWS.
     for (var i = 0; i < jsonData.length; i++) { // EXTRACT VALUE FOR HTML HEADER. 
        var newRow=createPlaylistEntry(jsonData[i]);
        table.appendChild(newRow);
     }

 }

function createPlaylistEntry(item) {    
    var songId=item.id,
        songLabel=item.label;
    var musicInfoDiv=document.createElement("div");
    musicInfoDiv.className="music-info";
    // track info
    // (...) several other html elements creation...
   var musicNameHeader=document.createElement("h6");
    musicNameHeader.innerHTML=songLabel;
    musicNameDiv.appendChild(musicNameHeader);
    var musicNamePerformer=document.createElement("p");
    musicNamePerformer.id="namePerformer"+songId;
    // TODO update performer name
    send_message("AudioLibrary.GetSongDetails",{"songid"ConfusedongId, "properties": ["album", "albumartist"] },"songDetails");
    musicNamePerformer.innerHTML="TODO";
    musicNameDiv.appendChild(musicNamePerformer);

    musicInfoDiv.appendChild(musicNameDiv);
    send_message("AudioLibrary.GetSongDetails",{"songid"ConfusedongId, "properties": ["album", "albumartist"] },"songDetails");
 
return musicInfoDiv;
}
 function send_message(method, params, id) {
     if(!id) id=method;
     var msg = {
         "jsonrpc": "2.0",
         "method": method,
         "id": id
     };
     if (params) {
         msg.params = params;
     }
     ws.send(JSON.stringify(msg));
 }
Reply
#5
I've tried this with other Kodi with v17 and the same thing happens...

Any ideas?

Luís
Reply
#6
For Kodi in general, I've found it best to wait for a response to one request over websocket before firing off another.

For this particular case, there is a "properties" param for Player.GetItems that you can set to ["album", "albumartist"] like you have for "GetSongDetails" and that info will be returned for all songs in one go. That should include options for every property that "GetSongDetails" has. This should also work for songs that are played from the file system and aren't in the library, if tag reading is on.
Reply
#7
Hi rmrector,

Thanks for your suggestion, it solved my problem. I didn't know I could specify those properties, and that's why I was using this alternative...

The problem I described seems to be there, though... And maybe it's not just an async problem: I tried creating a new webSocket for each of the messages I was sending concomitantly, and still some responses were not received... The behaviour was similar to the one I described above. There is, thus , possibly a bug in this scenario.

Thanks again and bye, Luís
Reply
#8
(2019-01-07, 13:38)lumo Wrote: The problem I described seems to be there, though... And maybe it's not just an async problem: I tried creating a new webSocket for each of the messages I was sending concomitantly, and still some responses were not received... The behaviour was similar to the one I described above. There is, thus , possibly a bug in this scenario.

Yeah, there is definitely room for improvement there. In practice, I haven't had a problem with several applications tripping each other up over websockets, it's just blasting several of them down the line at the same exact time isn't handled well, so processes like this should wait for each response before going to the next.
Reply
#9
@lumo Any chance you can provide your finished code? It would be greatly appreciated. Thank you.
Reply

Logout Mark Read Team Forum Stats Members Help
Not getting responses to all JSON-RPC messages sent: bug or feature?0