Поставлена задача - организовать печать по сети на мобильных принтерах производства компаний TSC и Zebra без необходимости установки на серверах драйверов принтеров, регистрации и СМС. В эксплуатации находятся несколько десятков принтеров. Подключение к общей сети выполнено по Wi-Fi. Печать необходимо производить из трех видов приложений: "1С-Управление торговлей", приложения для ТСД, мобильного приложения для обычных смартфонов/планшетов (при этом мобильное приложение непосредственного доступа в корпоративную сеть не имеет). Печатные формы генерируются обработкой в 1С в виде скриптов на языках разметки TSPL/ZPL.
Решение: поскольку в сети уже есть Web-сервер под IIS, где подняты Web-сервисы и HTTP-сервисы для мобильных приложений, то на сервере дополнительно запускаем скрипт на PHP, на вход принимающий пакет данных, где содержится IP принтера и скрипт на TSPL/ZPL, и отправляющий данные по IP-адресу принтера.
Пакет формируется в JSON, выглядит следующим образом:
Шаблон кодируется в base64, поскольку в командах TSPL/ZPL могут быть символы, невалидные для JSON.
{
"printer_ip":"192.168.X.XXX",
"template":"Здесь должен быть шаблон этикетки, закодированный в base64"
}
Схема работы для печати ценника, например, следующая - в мобильном приложении сканируется ШК товара, на сервер уходит пакет данных с этим ШК, кодом пользователя/магазина/отдела, в 1С по ним формируется вышеприведенный пакет, и из 1С же методом POST передается по URL на Web-сервере в скрипт на PHP. Результат выполнения скрипта анализируется, и передается мобильному приложению.
Собственно, базовый функционал скрипта выглядит следующим образом:
<?php
class M_Response {
public $success;
public $reason;
}
error_reporting(E_ALL);
ob_implicit_flush(1);
$mresponse = new M_Response();
$entityBody = file_get_contents('php://input');
// получили на входе пакет в JSON
if ($entityBody === false || $entityBody === null || $entityBody === "") {
// Что-то пошло не так, вернем статус и причину ошибки
$mresponse->success = false;
$mresponse->reason = "Ошибка при получении исходных данных";
http_response_code(400);
$respJSON = json_encode($mresponse , JSON_UNESCAPED_UNICODE);
echo $respJSON;
exit();
}
$obj = json_decode($entityBody);
if ($obj === false || $obj === null) {
$mresponse->success = false;
$mresponse->reason = "Ошибка декодирования входных данных";
http_response_code(400);
$respJSON = json_encode($mresponse , JSON_UNESCAPED_UNICODE);
echo $respJSON ;
exit();
}
$template = $obj->template;
$decoded_template = base64_decode($template);
if ($decoded_template === false || $decoded_template === null) {
$mresponse->success = false;
$mresponse->reason = "Ошибка декодирования шаблона печати";
http_response_code(400);
$respJSON = json_encode($mresponse , JSON_UNESCAPED_UNICODE);
echo $respJSON ;
exit();
}
$service_port = 9100;
$address = $obj->printer_ip;
// Данные передаем через TCP-socket (описание этого метода есть на сайтах производителей принтеров)
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
$reason = socket_strerror(socket_last_error());
// IIS на сервере отдает сообщения в Win-1251, потому перекодируем
// для других серверов, возможно, это и не понадобится
$reason2 = iconv("Windows-1251", "UTF-8", $reason);
$mresponse->success = false;
$mresponse->reason = $reason2;
http_response_code(400);
} else {
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
$reason = socket_strerror(socket_last_error());
$reason2 = iconv("Windows-1251", "UTF-8", $reason);
$mresponse->success = false;
$mresponse->reason = $reason2;
http_response_code(400);
} else {
$result = socket_write($socket, $decoded_template, strlen($decoded_template));
if ($result === false) {
$reason = socket_strerror(socket_last_error());
$reason2 = iconv("Windows-1251", "UTF-8", $reason);
$mresponse->success = false;
$mresponse->reason = $reason2;
http_response_code(400);
}
else {
$mresponse->success = true;
$mresponse->reason = "";
http_response_code(200);
}
socket_close($socket);
}
}
$respJSON = json_encode($mresponse, JSON_UNESCAPED_UNICODE);
echo $respJSON ;
?>