jamulus icon indicating copy to clipboard operation
jamulus copied to clipboard

Integration and deprecation of -m option in favor of JSON RPC

Open ann0see opened this issue 1 year ago • 3 comments

It is worth discussing deprecating the -m option and/or integrating missing features it into JSON RPC. It's not a core feature of Jamulus.

I think we had this discussion a while ago. Cc: @pljones

https://github.com/jamulussoftware/jamuluswebsite/pull/1019#discussion_r1730305176

ann0see avatar Aug 30 '24 19:08 ann0see

Yep, --htmlstatus should probably be marked deprecated in 3.12.0. The client list is available from the server either over UDP (acting as a client, the way @softins's PHP does it) or using the JSON-RPC calls.

pljones avatar Aug 30 '24 19:08 pljones

The website already calls it deprecated today: https://jamulus.io/wiki/Running-a-Server#-m-or---htmlstatus

I think we should

  • [x] Update the help output in Jamulus to say it's deprecated (https://github.com/jamulussoftware/jamulus/pull/3398)
  • [x] Issue a warning in Jamulus if the -m option is invoked (https://github.com/jamulussoftware/jamulus/pull/3398)
  • [x] Remove all references to it on the website (https://github.com/jamulussoftware/jamuluswebsite/pull/1087)
  • [x] Write a discussion post with example how to get the all the outputs from the other APIs (https://github.com/orgs/jamulussoftware/discussions/3508#discussion-8540770)

ann0see avatar Aug 30 '24 20:08 ann0see

Ok. After checking the output it's really just the connected clients' names.

ann0see avatar Aug 30 '24 20:08 ann0see

I am not 100% confident, but a raw PHP script with sockets (and without any library) could look like this. I do see that there could be problems if messages come in out of order:

<?php

function loadserverstat($rpcsecret, $jsonrpcport) {
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if (!socket_connect($socket, "localhost", $jsonrpcport)) {
        echo "Could not connect to Jamulus JSON-RPC endpoint. Please check for connectivity errors.";
        exit(1);
    }

    $auth = json_encode(["id" => 1, "jsonrpc"=>"2.0", "method"=>"jamulus/apiAuth", "params"=> ["secret" => $rpcsecret]]) . PHP_EOL;
    if (!socket_write($socket, $auth, strlen($auth)) == strlen($auth)) {
        echo "Could not start authentication with Jamulus JSON-RPC endpoint";
        exit(1);
    }

    $authResponse = socket_read($socket, 4096, PHP_NORMAL_READ);
    if (!$authResponse) {
        echo "Could not read authentication from Jamulus JSON-RPC endpoint.";
        exit(1);
    }

    $resp = json_decode($authResponse);
    if (isset($resp->result) && $resp->result == "ok") {
        // authenticated
        // check if server
        $modeRequest = json_encode(["id" => 2, "jsonrpc"=>"2.0", "method"=>"jamulus/getMode", "params"=> ["m" => "g"]]) . PHP_EOL;
        if (!socket_write($socket, $modeRequest, strlen($modeRequest)) == strlen($modeRequest)) {
            echo "Could not request server or client mode";
            exit(1);
        }

        while ($res = socket_read($socket, 4096, PHP_NORMAL_READ)) {
            $encodedRes = json_decode($res);
            if (!$encodedRes) {
                // failed to decode
                error_log("Could not decode string from server");
                continue;
            }
            if ($encodedRes->id === 2 && $encodedRes->result->mode === "server") {
                break;
            } else {
                echo "Jamulus is not running as a server" . PHP_EOL;
                exit(1);
            }
        }
        // get the client list

        $clientListRequest = json_encode(["id" => 3, "jsonrpc"=>"2.0", "method"=>"jamulusserver/getClients", "params"=> ["m" => "g"]]) . PHP_EOL;
        if (!socket_write($socket, $clientListRequest, strlen($clientListRequest)) == strlen($clientListRequest)) {
            echo "Could not request client list";
            exit(1);
        }


        while ($res = socket_read($socket, 8192, PHP_NORMAL_READ)) {
            // TODO: depending on the response length: bump up the number of bytes to read
            $encodedRes = json_decode($res);
            if (!$encodedRes) {
                // failed to decode
                error_log("Could not decode string from server");
                continue;
            }

            if ($encodedRes->id === 3) {
                print "<ul>";
                foreach ($encodedRes->result->clients as $client) {
                    print "<li>" . htmlspecialchars($client->name) . "</li>";
                }
                print "</ul>" . PHP_EOL;
                break;
            }
        }
    } else {
        echo "Could not authenticate. Please check your password";
        exit(1);
    }
    
}

echo loadserverstat("<yourjsonrpcsecrethere>", <yourjsonrpcporthere>);

I think it could serve as example without any guarantees. We might point users to libraries or nodejs based workflows which should work better.

ann0see avatar Jul 02 '25 19:07 ann0see

Closing as announcement is now out: https://github.com/orgs/jamulussoftware/discussions/3508

ann0see avatar Jul 06 '25 09:07 ann0see