RabbitMQ: отложенные сообщения

Задача: организовать доставку сообщения «слушателю» спустя какое-то время, а не сразу

Решение: одним из способов реализации является использование модуля rabbitmq-delayed-message-exchange.

Установка для Ubuntu:

  1. Скачать подходящую версию модуля для версии вашего RabbitMQ в формате *.ez
  2. Положить его в папку (в моём случае) /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.9/plugins
  3. Включить плагин
rabbitmq-plugins enable rabbitmq_delayed_message_exchange

Использование:

Пример постановки в очередь:



define('WUO_ROOT', dirname(__FILE__));

require_once WUO_ROOT.'/../vendor/autoload.php';
// загружаем классы
spl_autoload_register(function ($class_name) {
    require_once WUO_ROOT.'/../class/'.$class_name.'.php';
});

//Необходимые классы
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

//Создаем соединение
$connection = new AMQPStreamConnection('22.357.184.20', 5672, 'цсцаучсцу', 'сысыуксыук');

//Берем канал и декларируем в нем новую очередь, первый аргумент - название
$channel = $connection->channel();

// Очередь
$channel->queue_declare('wss_messages', false, true, false, false);

// Отправляю 5 сообщений
for ($i=0;$i<6;$i++){
    $msg = new AMQPMessage("Hello All №".$i, ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);		
    $msg->set('application_headers', new AMQPTable(['x-delay' => 5000]));
    $channel->basic_publish($msg, 'main');
};
echo "Messages sended\n";
$channel->close();
$connection->close();

Пример слушателя:



define('WUO_ROOT', dirname(__FILE__));
require_once WUO_ROOT.'/../vendor/autoload.php';
// загружаем классы
spl_autoload_register(function ($class_name) {
    require_once WUO_ROOT.'/../class/'.$class_name.'.php';
});

//Необходимые классы
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

//Создаем соединение
$connection = new AMQPStreamConnection('22.53.14.120', 5672, 'уцмцу', 'мцукмцукм');
$channel = $connection->channel();

$channel->queue_declare('wss_messages', false, true, false, false);

$callback = function ($msg) {
        echo $msg->body;
        echo PHP_EOL;
};
$channel->basic_qos(null, 1, null);
$channel->basic_consume('wss_messages', '', false, true, false, false, $callback);

while (count($channel->callbacks)) {
        $channel->wait();
}
$channel->close();
$connection->close();

1С: Узнать позицию в цикле

Задача: узнать текущую позицию для цикла вида

для каждого стр_расчеты из КадастроваяСтоимость цикл
конеццикла

Решение: учить матчасть (с)

для каждого стр_расчеты из КадастроваяСтоимость цикл
  поз=КадастроваяСтоимость.Индекс(стр_расчеты);
конеццикла

JavaScript: создаем и позволяем скачать csv файл

Задача: из некого массива данных создать файл и предложить его к закачке пользователем, без участия серверной части.

Решение: Для создания файла воспользуемся функцией Blob, которая позволяет оперировать с бинарными данными. Далее создадим в DOM элемент <a>, поместим в href бинарные данные и сэмулируем нажатие на ссылку. Примерно так:

  //собираем csv файл
                      csv="OKPU;P1;P2;\n";
                      data.result.forEach(function(entry) {
                        csv=csv+entry.okpu+";"+entry.P1+";"+entry.P2+"\n";  
                      });
                        let a = document.createElement("a");
                        let file = new Blob([csv], {type: 'application/csv'});
                        a.href = URL.createObjectURL(file);
                        a.download = "sender_okpu_data.csv";
                        a.click();

1С: Скачать файл через http сервис

Задача: в веб интерфейс сайта вывести кнопку получения файла со стороны 1С

Решение:

На стороне 1с оформим сервис по примеру:

HTTPОтвет = Новый HTTPСервисОтвет(200);
						
							ЗаписьЖурналаРегистрации("Пришло в HTTP.имя файла", УровеньЖурналаРегистрации.Информация,,имяфайла,имяфайла+"!",);	
				
				ДВ = Новый ДвоичныеДанные(имяфайла);						
				
			    HTTPОтвет.УстановитьТелоИзДвоичныхДанных(ДВ);
				HTTPОтвет.Заголовки["Content-Description"]="File Transfer";
				HTTPОтвет.Заголовки["Pragma"]="public";
				HTTPОтвет.Заголовки["Expires"]="0";
				HTTPОтвет.Заголовки["Cache-Control"]="must-revalidate, post-check=0, pre-check=";
				HTTPОтвет.Заголовки["Cache-Control"]="public";
				HTTPОтвет.Заголовки["Content-Type"]="text/plain; charset=UTF-8";
			    HTTPОтвет.Заголовки["Content-Type"] = "application/invoice.pdf";
    			HTTPОтвет.Заголовки["Content-Disposition"] = "attachment; filename=chet.pdf";		
		Возврат HTTPОтвет;		

На стороне сайта, можно оформить в виде:


class TApi1c {
    public $url="";
    public $login="";
    public $password="";
    public function __construct($url,$login,$password) {
        $this->url=$url;
        $this->login=$login;
        $this->password=$password;
    }    
    public function reqwest($reqwest,$body=array()){
        if (LK_DEBUG==true):
            $data=Date("m-d-y h:i:s")." - посылаем в подсистему 1C $reqwest  :\n";
            $data=$data.json_encode($body)."\n";
            file_put_contents(API_LOG_FILE, $data,FILE_APPEND);
        endif;
        $ch = curl_init($this->url);
            curl_setopt($ch, CURLOPT_USERPWD, $this->login.":".$this->password);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); 
            $js["reqwest"]=$reqwest;
            $js["body"]=$body;
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($js));
            //curl_setopt($ch, CURLOPT_TIMEOUT, 300);
            $res=curl_exec($ch);            
            if (LK_DEBUG==true):
                $data=Date("m-d-y h:i:s")." - сырой ответ  :\n";
                $data=$data.serialize($res)."\n";
                file_put_contents(API_LOG_FILE, $data,FILE_APPEND);
            endif;
            
            //echo "!!";
            //var_dump($res);                
            //echo "!!";
            $response = json_decode($res);
            if ($response==null){
              AddErrorMessage("Ошибка","Внутрення ошибка сервера. Попробуйте позже.");                
              if (LK_DEBUG==true):
                  file_put_contents(API_LOG_FILE, $data,FILE_APPEND);
              endif;
            };             
            return $response;             
        if(curl_errno($ch)){
            throw new Exception(curl_error($ch));
        };        
    }  
}

class TInvoice {
    public $api="";         // класс работы с API
    public function __construct($api){
        $this->api=$api;
    }    
    public function GetInvoice($hash){
          $req["hash"]=$hash;
          $res=$this->api->naked_reqwest("GetInvoice",$req);
          if ($res!=null){          
              return $res;
          } else {
            $res = new \stdClass();
            $res->error=true;
            $res->result="Сервер не доступен. Попробуйте позже.";          
                AddErrorMessage("Ошибка",$res->result);
          }; 
          return $res;
        }   
}      

$Api1c=new TApi1c(url_1c,user_1c,password_1c);


if (isset($_GET["id"])==false){$_GET["id"]="";};

$id=$_GET["id"];
$inv=new TInvoice($Api1c);
$res=$inv->GetInvoice($id);
if (($res!="error") or ($res!="notfound")){
    header('Content-type: application/pdf');
    header("Content-Disposition: attachment; filename=invoice.pdf");
    header("Pragma: no-cache");
};
echo $res;  

1С: быстрая очистка большого регистра сведений

Самый простой способ — создать пустую запись без фильтров:

НаборЗаписей = РегистрыСведений.наш_регистр.СоздатьНаборЗаписей();
НаборЗаписей.Записать();

1 73 74 75 76 77 310