Code: Select all
tool netwatch enable [find host~"192.168.1.12"]
tool netwatch enable [find host~"192.168.1.12"]
<?php
namespace PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b3.phar';
$client = new Client('192.168.1.1', 'admin', 'password');
$printRequest = new Request(
'/tool netwatch print .proplist=.id',
Query::where('host', '192.168.1.120', Query::ACTION_GREATHER_THAN)
->andWhere('host', '192.168.1.129', Query::ACTION_LESS_THAN)
->orWhere('host', '192.168.1.120')
->orWhere('host', '192.168.1.129')
->orWhere('host', '192.168.1.12')
);
$idList = '';
foreach ($client->sendSync($printRequest)->getAllOfType(Response::TYPE_DATA) as $response) {
$idList .= $response->getArgument('.id'), ',';
}
$idList = rtrim($idList, ',');
$enableRequest = new Request('/tool netwatch enable');
$enableRequest->setArgument('numbers', $idList);
$client->sendSync($enableRequest);
Can it work without PEAR2?
Yes. You get the PHAR file, and include it, as in the code above. Everything required is bundled within the PHAR. No need for you to have PEAR or PEAR2.
$ARRAY = $API->comm('/tool/netwatch/print');
for ($i=0; $i<250; $i++)
{
$regtable = $ARRAY[$i];
$IP=$regtable['host'];
$id=$regtable['.id'];
if ($IP==$host) {
$ARRAY = $API->comm("/tool/netwatch/enable", array(
'.id'=> ''.$id.'',));
}
}
Overall, I came up with this, and it works flawlessly, but I want to ask, in terms of performance, which is going to perform better?
And one more question, how do you make the MikroTik send requests, because for that, I use the fetch.
My code is definetly going to be faster - here, you go over everything in netwatch and check it, whereas with mine, the MikroTik checks them, after which PHP receives only the necessary.
And the fact that as you've written it, only a single specific IP is going to be searched for (instead of any IP starting with 192.168.1.12), is just "by the way".
As for sending (HTTP?) requests... the fetch of course. There isn't anything else.
:local imeNaFaila "file.rsc"
/file set $imeNaFaila contents=([/file get $imeNaFaila contents] . "\nСъдържание на нов ред")
So that I don't create a new topic, I want to ask: do you have an idea how I could make a script at MT, that would write a new line in an rsc file?
Something like this?
But keep in mind that the bigger the file gets, the more RAM it will take from the router, since the whole contents is loaded before being appended to. If you want that not to happen, you'll have to use, for example, PHP, where the file will be downloaded and appended to by the web server, after which the result will be sent back. In this way, instead of "more RAM", you need more time (due to the transfers between the router and the web server).
If this file is some sort of backup, maybe it would be best if you just do whatever you'd do, and do an export at the end.
No, the idea is to save all undelivered fetch requests, and maybe run it at some time for reevaluation
Then the file is probably not going to get much big => the above should work for you.
I would use PHP with some database (where the failed requests will be stored), after which I'd upload what I must at the router. In fact, if you use the API, no uploading is necessary. You just use the API to make a fetch, and save the URL at the DB on failure.
<?php
namespace PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b3.phar';
$client = new Client('192.168.1.1', 'admin', 'password');
$client->sendAsync(
new Request('/tool fetch url="http://example.com/index.html" keep-result="yes"', null, 'f'),
function ($response) {
switch ($response->getArgument('status')) {
case 'failed':
//Запис в базата данни тук
//Без break;
case 'finished':
return true;
}
}
);
$client->loop();
OK, but how is the external server going to understand that the request hasn't been received.
Actually, a response always arrives. The only question is if it's the response you expect.
If the status is "finished", then the request produced a file with code 200 (OK). In other circumstances, the status is "failed".
There's a bug with the "fetch" command under the API protocol, in that it doesn't stop automatically... with my client, this is easy to workaround. Example:
С горния метод, заявката се изпълнява от рутера. Сървъра просто кара рутера да изпълни заявката.Това е ясно, но ще работи когато заявката за fetch се изпълнява от сървъра. А моята идея е да я изпълнява рутера
This is all right, but it will work when the fetch request is ran by the server. And my idea instead is for the router to run it.
With the code above, the request is ran by the router. The server only makes the router do the request.
i.e. the situation is
server --> API request to router
router --> HTTP request to external server
external server --> HTTP response to router (transmits file contents)
router --> API response to server (does NOT transmit file contents, but only the status)
The only difference is in where YOU click the button/schedule. Yes, with the above, the schedule will have to be on the server, but the request itself is still performed at the router (and the response goes directly there, instead of passing through the server).
Instead of scheduling the server, you could make the router periodically send a single HTTP request to the server, which would in turn make the router do everything else. i.e.
router --> HTTP request to server
server --> API request to router
...
That way, you can have both the router starting the procedure, and have full control over the whole process while in PHP.
Yeah, but the very idea of the whole code is for the router to send a request to the server on a certain event.
What's this event? Give the full scenario... perhaps there's a way to make it more elegant.
Е да де. Точно това предлагам и аз.Интересно решение, които ми дава друга идея, че за да не се налага по някакъв начин периодично изпълнение на скрипт от Web сървъра. Може да го организирам нещата, така че при промяна в статуса на netwatch да се стартира скрипт, който да кара web сървъра да изтегли сам записания файл и да си обнови информацията?
Така би ли следвало да се използват най-малко ресурси?
Част от отговорността на RouterOS като операционна система е автоматично да поставя ключалки за четене и писане - ако четенето дойде първо, писането чака четенето да свърши преди да пише и обратното.И един малък въпрос, какво би станало ако по време на четене на файла се записва в него?
[/file get $imeNaFaila contents]
<?php
require_once 'PEAR2_Net_RouterOS-1.0.0b3.phar';
$trans = new PEAR\Net\Transmitter\Stream($file = fopen('ftp://admin:password@192.168.1.1/192.168.1.12.txt', 'r+b'));
$mysqli = new mysqli('127.0.0.1', 'root', '', 'db');
$query = "INSERT INTO `failures` (`dateTime`) VALUES ";
try {
while (true) {
//21 === strlen("mmm/DD/YYYY-HH:MM:SS\n")
$dateTime = DateTime::createFromFormat('M/j/Y-H:i:s', ucfirst(rtrim($trans->receive(21))))
->format('Y-m-d H:i:s');
$query .= "('" . $mysqli->real_escape_string($dateTime) . "'), ";
}
} catch (Exception $e) {
//Приключихме с четенето на файла ИЛИ връзката е прекъснала по време на четенето.
}
$query = rtrim($query, ', ');
$mysqli->query($query);
ftruncate($file, 0);//Изчиства файла