JSON-RPC Notes

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • vining
    Senior Member
    • Mar 2010
    • 115

    JSON-RPC Notes

    I just started playing w/ JSON and I've found information to be scattered and vague so I'm going to put what I've discovered so far here in case someone else is going to give this a try. The language I'm using (AMX's Neltinx) doesn't have all the various functions and handlers that other languages do which is why most of the references and examples I've found to be pretty much useless.

    In my code I open a TCP socket to the IP of my LMS on port 9000.

    When the connection is established I'm issued and "ONLINE" event to let me know the connection has been established and I use that to trigger sending my queued commands to LMS.

    Here's some valid commands string that I used for testing:
    Code:
     {"id":1,"method":"slim.request","params":["00:04:20:1a:ea:f6",["status","-",1,"tags:al"]]} 
     {"id":1,"method":"slim.request","params":[ "", ["albums", "0","50" ]]}
     {"id":1,"method":"slim.request","params":["00:04:20:1a:ea:f6",["play"]]}
     {"id":1,"method":"slim.request","params":["00:04:20:1a:ea:f6",["status","-",1,"tags:uB"]]}
     {"id":1,"method":"slim.request","params":["",["serverstatus",0,999]]}
    Prior to sending the string I populate my variable to hold a string:
    Code:
    sJSON.sPlayer.cCmd = '{"id":1,"method":"slim.request","params":["00:04:20:1a:ea:f6",["status","-",1,"tags:uB"]]}';
    The single quotes indicates a string literal.


    Wireshark intercepts between PC and LMS running on a remote vortexbox showed the exchange coming from the PC to control LMS and I modified it into the format I need to send these strings from an AMX controller.
    Code:
                        SEND_STRING dvJSON,"'POST /jsonrpc.js HTTP/1.1',STR_CRLF"; 
    		    SEND_STRING dvJSON,"'Host: ',sJSON.sPlayer.cIP,':',itoa(sJSON.sPlayer.nPort),STR_CRLF";
    		    SEND_STRING dvJSON,"'User-Agent: User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:27.0) Gecko/20100101 Firefox/27.0',STR_CRLF";
    		    SEND_STRING dvJSON,"'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',STR_CRLF"; 
    		    SEND_STRING dvJSON,"'Accept-Language: en-us',STR_CRLF";
    		    SEND_STRING dvJSON,"'Accept-Encoding: gzip, deflate',STR_CRLF";
    		    SEND_STRING dvJSON,"'X-Requested-With: XMLHttpRequest',STR_CRLF";
    		    SEND_STRING dvJSON,"'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',STR_CRLF";
    		    SEND_STRING dvJSON,"'Referer: http://',sJSON.sPlayer.cIP,':',itoa(sJSON.sPlayer.nPort),'/',STR_CRLF";
    		    SEND_STRING dvJSON,"'Content-Length: ',itoa(length_string(sJSON.sPlayer.cCmd)),STR_CRLF";
    		    SEND_STRING dvJSON,"'Cookie: Squeezebox-player=',fnEncodeURL(sJSON.sPlayer.cStrMAC),'; Squeezebox-expandPlayerControl=false; ',
    		    'Squeezebox-expanded-MY_MUSIC=1; Squeezebox-expanded-RADIO=0; Squeezebox-expanded-PLUGIN_MY_APPS_MODULE_NAME=1; ',
    		    'Squeezebox-expanded-FAVORITES=0; Squeezebox-expanded-PLUGINS=0; Squeezebox-playersettings=null; ',
    		    'Squeezebox-advancedsettings=settings/server/debugging.html%3F; Squeezebox-expanded-updatePlugins=1; ',
    		    'Squeezebox-expanded-activePlugins=1; Squeezebox-expanded-inactivePlugins=1; Squeezebox-expanded-otherPlugins0=1; ',
    		    'Squeezebox-expanded-otherPlugins1=1; __utma=124789194.27251913.1391382619.1391382619.1391382619.1; ',
    		    '__utmz=124789194.1391382619.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',STR_CRLF";
    		    SEND_STRING dvJSON,"'Connection: keep-alive',STR_CRLF";
    		    SEND_STRING dvJSON,"'Pragma: no-cache',STR_CRLF";
    		    SEND_STRING dvJSON,"'Cache-Control: no-cache',STR_CRLF";
    		    SEND_STRING dvJSON,"STR_CRLF";
    		    SEND_STRING dvJSON,"sJSON.sPlayer.cCmd,STR_CRLF";
    Again single quotes indicate a string literal and the double quotes outside concatenate different variables and data types into a single string for sending. STR_CRLF is just a constant for carriage return, line feed (Hex $0d,$0a or decimal 13,10).

    After playing around a little I found the server will function just fine if only sent, maybe less but it's reduced enough for me:
    Code:
                        SEND_STRING dvJSON,"'POST /jsonrpc.js HTTP/1.1',STR_CRLF"; 
    		    SEND_STRING dvJSON,"'Host: ',sJSON.sPlayer.cIP,':',itoa(sJSON.sPlayer.nPort),STR_CRLF";
    		    SEND_STRING dvJSON,"'Referer: http://',sJSON.sPlayer.cIP,':',itoa(sJSON.sPlayer.nPort),'/',STR_CRLF";
    		    SEND_STRING dvJSON,"'Content-Length: ',itoa(length_string(sJSON.sPlayer.cCmd)),STR_CRLF";
    		    SEND_STRING dvJSON,"STR_CRLF";
    		    SEND_STRING dvJSON,"sJSON.sPlayer.cCmd,STR_CRLF";
    I haven't played around to see if the connection can be maintained or if I need to open the socket and close it for every command which would be typical for http.
  • pippin
    Senior Member
    • Oct 2007
    • 14809

    #2
    One thing: don't expect strings and numbers to be typed correctly. A text field (like an a album name) containing only a number will be sent as a number and sometimes numbers are enclosed in quotation marks.

    JSON/RPC commands _should_ be sent as http POST requests to /jsonrpc on your server. Or you can use an IP stream using the cometd protocol but this is a bit more complex since what Logitech does doesn't always conform to the standard.
    ---
    learn more about iPeng, the iPhone and iPad remote for the Squeezebox and
    Logitech UE Smart Radio as well as iPeng Party, the free Party-App,
    at penguinlovesmusic.com
    New: iPeng 9, the Universal App for iPhone, iPad and Apple Watch

    Comment

    • vining
      Senior Member
      • Mar 2010
      • 115

      #3
      Originally posted by pippin
      One thing: don't expect strings and numbers to be typed correctly. A text field (like an a album name) containing only a number will be sent as a number and sometimes numbers are enclosed in quotation marks.

      JSON/RPC commands _should_ be sent as http POST requests to /jsonrpc on your server. Or you can use an IP stream using the cometd protocol but this is a bit more complex since what Logitech does doesn't always conform to the standard.
      Thanks, I'll keep that in mind when I get around to writing a parsing routine. First I have find where I gain benefits over CLI. I know CLI stops working at a certain point in Triode's Spotify so maybe I'll start testing with that.

      Comment

      • mherger
        Babelfish's Best Boy
        • Apr 2005
        • 24630

        #4
        JSON-RPC Notes

        > SEND_STRING dvJSON,"'Cookie: Squeezebox-player=',fnEncodeURL(sJSON.sPlayer.cStrMAC),'; Squeezebox-expandPlayerControl=false; ',
        > 'Squeezebox-expanded-MY_MUSIC=1; Squeezebox-expanded-RADIO=0; Squeezebox-expanded-PLUGIN_MY_APPS_MODULE_NAME=1; ',
        > 'Squeezebox-expanded-FAVORITES=0; Squeezebox-expanded-PLUGINS=0; Squeezebox-playersettings=null; ',
        > 'Squeezebox-advancedsettings=settings/server/debugging.html%3F; Squeezebox-expanded-updatePlugins=1; ',
        > 'Squeezebox-expanded-activePlugins=1; Squeezebox-expanded-inactivePlugins=1; Squeezebox-expanded-otherPlugins0=1; ',
        > 'Squeezebox-expanded-otherPlugins1=1; __utma=124789194.27251913.1391382619.1391382619.13 91382619.1; ',
        > '__utmz=124789194.1391382619.1.1.utmcsr=(direct)|u tmccn=(direct)|utmcmd=(none)',STR_CRLF";


        Keep it simple: you can probably ignore most headers. Cookies aren't
        needed for sure.

        --

        Michael
        Michael

        "It doesn't work - what shall I do?" - "Please check your server.log and/or scanner.log file!"
        (LMS: Settings/Information)

        Comment

        • vining
          Senior Member
          • Mar 2010
          • 115

          #5
          Originally posted by mherger
          > SEND_STRING dvJSON,"'Cookie: Squeezebox-player=',fnEncodeURL(sJSON.sPlayer.cStrMAC),'; Squeezebox-expandPlayerControl=false; ',
          > 'Squeezebox-expanded-MY_MUSIC=1; Squeezebox-expanded-RADIO=0; Squeezebox-expanded-PLUGIN_MY_APPS_MODULE_NAME=1; ',
          > 'Squeezebox-expanded-FAVORITES=0; Squeezebox-expanded-PLUGINS=0; Squeezebox-playersettings=null; ',
          > 'Squeezebox-advancedsettings=settings/server/debugging.html%3F; Squeezebox-expanded-updatePlugins=1; ',
          > 'Squeezebox-expanded-activePlugins=1; Squeezebox-expanded-inactivePlugins=1; Squeezebox-expanded-otherPlugins0=1; ',
          > 'Squeezebox-expanded-otherPlugins1=1; __utma=124789194.27251913.1391382619.1391382619.13 91382619.1; ',
          > '__utmz=124789194.1391382619.1.1.utmcsr=(direct)|u tmccn=(direct)|utmcmd=(none)',STR_CRLF";


          Keep it simple: you can probably ignore most headers. Cookies aren't
          needed for sure.

          --

          Michael
          Yeah, I a big fan of simple and I've been using the shorter version that I posted once I determined that was enough to satisfy the server. IMHO CLI is even simpler but I can see the need for the connection less http protocol for most situations.

          Comment

          • nikclayton
            Junior Member
            • Jul 2014
            • 15

            #6
            If anyone's interested, I've started trying to document this at https://docs.google.com/document/d/1...it?usp=sharing.

            You should be able to comment on the doc with that link -- select some text, hit "Insert > Comment" -- if you've got anything to add.

            It's pretty barebones at the moment, I'm hoping the community can help flesh it out.

            Comment

            Working...