I recently received privately a bug report about my API client that doing “/system/reboot” with it causes an exception in PHP.
Some debugging showed that “/system/reboot” causes a !done response, after which the connection is terminated, as per the effect of “/system/reboot”.
IMHO, this is wrong.
Any command that ends up terminating the connection like “/system/reboot” and “/system/shutdown” should instead end with a !fatal response, just like “/quit”, to more gracefully alert clients that the connection is over. I can understand that if a script causes a reboot/shutdown, this can’t be propagated to a currently connected API client, but at least a direct API call by the API client should have this effect.
I’ll of course work around this flaw in my API client’s next version anyway, for the sake of current RouterOS versions, but I’m reporting this for future’s sake…
IT comes down to design philosophy but I’d have to disagree - the action of /system/reboot is !done, meaning I have successfully rebooted the system for you, which in turn translates to correct usage [to me and my personal design philosophies]
By that logic, “/quit” should also not end with !fatal, since it’s a successful user triggered connection close. Except it currently does end with !fatal.
And before you say “Yes! THAT should be changed!”…
The purpose of !fatal in general is to alert the API client that the connection is about to be closed. Without !fatal, there’s no way for an API client to know at the time of the next call whether the connection is closed, or if the client is simply too slow to respond. With !fatal, the API client knows “The remote end does not respond, and that’s correct, that’s no need to keep my end of the connection opened”. I’ll admit “!fatal” is a somewhat misleading name for this purpose… I would’ve preferred “!final”, “!last” or “!end”, but at this point, it’s a little too late to change semantics.
Hello Vasil Rangelov,
Could you help me with “/system/reboot” using your API PHP.
When I try use the above command, my Router reboot but my browser freeze and I lost communication with my interface administrative domain. And I only reconnect if i close and re-open my browser.
How can I use AJAX(or submit) + your API for reboot a router?
I’m thinking about workaround add script, remove, exec script. But I don’t know if this is the correct way.
require_once '/pear/downloads/PEAR2_Net_RouterOS-1.0.0b5.phar';
...
try { $client = new RouterOS\Client($IP_MIKROTIK, $LOGIN_MIKROTIK, $PASS_MIKROTIK);
} catch (Exception $e) { $connect_status = 'error_01'; }
if (isset($client)) {
$connect_status = 'sucess';
$addRequest = new RouterOS\Request('/system/reboot');
if ($client->sendSync($addRequest)->getType() !== RouterOS\Response::TYPE_FINAL) {
$connect_status = 'error_03';
}
} else {
$connect_status = 'error_02';
}
...
Thank’s for your attention.
's
In 1.0.0b5, this issue should’ve been already resolved… It certainly is on Windows web servers. But after the release, I was made aware the issue still exists on Linux web servers, and I still don’t know how to solve it.
But yes, the current workaround is to create a scheduled script that would execute after some time (2 seconds is more than enough), and would remove itself before the reboot, while the connection safely closes before that.
$client->sendSync(new RouterOS\Request(
'/system scheduler add name=REBOOT interval=2s on-event="/system scheduler remove REBOOT;/system reboot"'
));
unset($client);//Safely close the connection before the actual reboot
If anyone finds a way to solve this for Linux too, I’d gladly implement it. Or even better - send me a pull request on GitHub, and I’ll merge it.