1C:Enterprise 8.3 Remote Administrative Client Utility for web application

In connection with the transition to domestic software, the organization had to look for a replacement for the Windows cluster administration utility. After studying the issue, it turned out that there are 3 approaches to administering a 1C cluster:

  1. External processing inside 1C – graphical interface, cross-platform. In a situation where all user licenses are occupied, but you need to see who and, if necessary, disconnect users who forgot to log out of 1c, this processing is useless.

  2. Windows cluster administration utility – graphical interface, only for Windows. Quite convenient, but it does not work under Russian operating systems (it may work under some wine, but this option is not always acceptable).

  3. The console utility rac (Remote Administrative Client) is cross-platform, but console-based. Of course, all the functionality is present, but I can’t say that it was very convenient.

After exploring alternative options, only one option was found, written in java. Cross-platform, with a beautiful web interface and very rich in features. A very good option, but its functionality was too much for me (one server, two dozen users).

I decided to make something of my own with the required minimum number of functions. First, we needed to decide how to receive data from 1C. Having studied the console application a little, I decided that the easiest way would be to make a small PHP script (the server was already running publishing 1C applications under Apache2), which would return responses from the console utility in the form of json, and use a javascript application for the user interface.

When the choice of tools was made, all that was left was to figure out how to send requests and parameters to the console utility (rac).

After studying the command line syntax, it turned out to be quite logical to pass all the request data through a GET request. Moreover, it is convenient to transmit commands as part of the URL – the path to the resource, and parameters as parameters. This resulted in the following request format:

http://localhost/192.168.1.2/infobase/summary/list?cluster=00000000-0000-0000-0000-000000000000

which was transformed into a command line like:

rac 192.168.1.2 infobase summary list —cluster=00000000-0000-0000-0000-000000000000

Thus, you can give any commands to the console utility via a URL.

Further, while studying the responses from the administration utility, it became clear that you need to divide the lines into the parameter name and its value using the colon symbol “:”, and separate one block of information from another using an empty line between the blocks.

After some time, I wrote a small script that does what I planned. In order not to constantly write the address of the administration server, I decided to add it to the command line assembly through the definition of the admServer constant. If necessary, it can be removed from the script (below is a listing of my index.php file with some comments).

<?php
define('pathToRac', '/opt/1cv8/x86_64/8.3.22.2106/rac');
define('admServer', '192.168.1.2');

We define the constants: pathToRac is the path in the administration utility, admServer is the IP address of the administration server (the port is standard, but you can specify it).

function responseToArray($response)
{
   $result = array();
   $object = array();

   if (count($response) > 0) {
      for ($i = 0; $i < count($response); $i++) {
         if ($response[$i] !== '') {
            preg_match('/(?<key>[^:]*)[ ]*:(?<value>.*)/', $response[$i], $matches);
            $object[trim($matches['key'])] = trim($matches['value']);
         } else {
            $result[] = $object;
            $object = array();
         }
      }
   }

   return $result;
}

The main function is responseToArray, which takes an array of response strings from the administration server as a parameter. In the loop, all lines are parsed through a regular expression into the parameter name and parameter value, placed in a temporary array, and when an empty line is detected, the elements of the temporary array are placed as a group in the resulting array. After the loop ends, the resulting array is returned.

$request = explode('?', $_SERVER['REQUEST_URI']);
$request = array_filter($request, 'strlen');
$parts = explode('/', $request[0]);
$parts = array_filter($parts, 'strlen');

Here the global variable REQUEST_URI is split by a question mark into two parts: the address and the parameters. Empty array elements ($request) are removed. The first part is taken ($request[0]) is the address and is divided into separate commands for the administration utility. Empty array elements ($parts) are also removed.

if (count($parts) > 0) {
   $commandLine = implode(' ', $parts);
   $params="";
   foreach ($_GET as $key => $value) {
      if ($key !== '' && $value !== '') {
         $params .= ' ' . '--' . $key . '=' . $value;
      }
   }

   $commandLine = pathToRac . ' ' . admServer . ' ' . $commandLine . $params;
   exec($commandLine, $outputArray, $retval);

If there are commands for rac, then we collect the command line. First, we combine all the commands into a line separated by a space. Next, we go through all the parameters passed through a GET request from the global array $_GET and collect them into the string variable $params, first adding two minus signs “–” before the parameter name, and after it an equal sign “=” and the value of the parameter. Next, we collect the entire command line into the $commandLine variable and pass it on for execution.

   if ($retval == 0) {
      preg_match('/Remote Administrative Client Utility/', $outputArray[0], $matches);
      if (count($matches) > 0) {
         $result['error'] = -1;
         $result['output'] = $outputArray;
      } else {
         $result['error'] = 0;
         $result['objects'] = responseToArray($outputArray);
      }
   } else {
      $result['error'] = $retval;
      $result['output'] = $outputArray;
   }

In this part, the result of the command is processed. If we get the exit code from the console utility equal to zero, then the utility worked normally and you can parse the results. If, as a result of execution, the first line of the management utility response includes the substring “Remote Administrative Client Utility”, then we will assume that this is not the result we need and check the box ($result[‘error’]) execution success to the value “-1”, we return the entire console output. And if there is no above specified substring, then we process the output from the console with our responseToArray function. If an error occurs, the value of the $retval variable will be greater than 0, so check the box ($result[‘error’]) to the value returned after executing the administration utility and passing the entire array of console output strings.

   header('Content-Type: application/json; charset=utf-8');
   echo json_encode($result);
} else {
   include_once('app.php');
}
?>

We wrap the response in json and transmit it to the client side. If no parameters are passed to the URL, then we connect the script responsible for the frontend.

For the above script to work, you still need to configure the web server (I have a setup for the apache2 server). Contents of the .htaccess file:

Options -Indexes
ErrorDocument 403 /

<Files *.php>
    deny from all
</Files>

<Files index.php>
    allow from all
</Files>

<IfModule mod_rewrite.c>
    RewriteEngine On
    Options +FollowSymlinks
    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php [L,QSA]
</IfModule>

This created a wrapper for a console utility that allows you to create a full-fledged web application.

Since the remote administration utility is console-based and does not provide real-time data, the client web application will have to periodically request data.

I hope my experience will be useful to someone. Thanks for taking the time to read.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *