satelles-odf-adiutor es una biblioteca PHP asincrónica basada en Swoole para la conversión de documentos mediante Unoserver.
Está pensada para integrarse con flujos de generación de reportes, documentos, tickets y plantillas ODF, permitiendo convertir archivos a otros formatos de forma eficiente, escalable y distribuida.
- Características
- Why this library?
- Requisitos
- Compatibilidad recomendada
- Instalación
- Configuración de Unoserver
- Quick start
- API principal
- Modos de operación
- Comparativa
filevsstream - Ejemplos incluidos
- Monitoreo de salud
- Recomendaciones de uso
- Estructura interna
- Contribución
- Licencia
- Integración con Unoserver mediante XML-RPC
- Procesamiento asincrónico con Swoole
- Balance de carga entre múltiples instancias de Unoserver
- Monitoreo de salud de servidores
- Manejo de reconexiones y reintentos automáticos
- Soporte para modo
streamy modofile - Resultados tipados mediante objetos de respuesta
- Alto rendimiento y tolerancia a fallos
Si ya generas documentos ODF en tu sistema, esta biblioteca te permite:
- convertir reportes y tickets a PDF u otros formatos
- distribuir la carga entre varias instancias de Unoserver
- evitar cuellos de botella en entornos con alta concurrencia
- obtener respuestas estructuradas y trazables
- integrar conversiones en flujos asincrónicos con Swoole
- PHP 8.1 o superior
- Extensión Swoole
- Unoserver
- LibreOffice
Aunque la biblioteca mantiene compatibilidad con PHP 8.1+, el entorno recomendado para despliegue actual es:
- PHP 8.4
- Swoole 6.2
composer require xvii/satelles-odf-adiutorPara usar la librería debes tener Unoserver ejecutándose en una o más instancias.
# Ejemplo iniciando 3 instancias
unoserver --port 2003 &
unoserver --port 2004 &
unoserver --port 2005 &# Usando systemd para múltiples instancias
for port in {2003..2005}; do
cat > /etc/systemd/system/unoserver-$port.service <<EOF
[Unit]
Description=Unoserver instance $port
[Service]
ExecStart=/usr/bin/unoserver --port $port
Restart=always
EOF
systemctl enable unoserver-$port
systemctl start unoserver-$port
doneRepite la configuración para cada instancia cambiando el puerto.
<?php
use Swoole\Coroutine;
use Tabula17\Satelles\Odf\Adiutor\Unoserver\ServerHealthMonitor;
use Tabula17\Satelles\Odf\Adiutor\Unoserver\UnoserverLoadBalancer;
$servers= new ConnectionCollection(
['host' => '127.0.0.1', 'port' => 2003],
['host' => '127.0.0.1', 'port' => 2004],
['host' => '127.0.0.1', 'port' => 2005],
];
$healthMonitor = new ServerHealthMonitor(
servers: $servers,
checkInterval: 30,
failureThreshold: 3,
retryTimeout: 60
);
$converter = new UnoserverLoadBalancer(
healthMonitor: $healthMonitor,
concurrency: 20,
timeout: 15
);
Coroutine\run(function () use ($converter, $healthMonitor): void {
$healthMonitor->startMonitoring();
$converter->start();
$result = $converter->convertAsync(
filePath: '/ruta/documento.odt',
outputFormat: 'pdf',
outPath: '/ruta/salida.pdf',
mode: 'file'
);
if ($result->isFile()) {
echo "Archivo generado en: {$result->outputPath}\n";
}
$converter->stop();
$healthMonitor->stopMonitoring();
});Se encarga de monitorear el estado de las instancias de Unoserver.
Responsabilidades principales:
- comprobar disponibilidad
- marcar servidores saludables o no saludables
- reintentar después de fallos
- exponer el conjunto de servidores saludables
Coordina la selección de servidores y ejecuta conversiones con reintentos.
Métodos principales:
start()stop()convertSync(...)convertAsync(...)getServerMetrics()
Cliente XML-RPC de bajo nivel para comunicación directa con Unoserver.
Responsabilidades:
- abrir conexión
- enviar request HTTP/XML-RPC
- procesar respuesta
- interpretar faults XML-RPC
- devolver un
UnoserverConversionResult
Objeto de resultado de conversión.
Propiedades expuestas:
modeinputPathoutputPathbase64ContentserverHostserverPort
Métodos auxiliares:
isStream()isFile()hasBase64Content()hasOutputPath()
Unoserver escribe directamente el archivo convertido en la ruta de salida.
$result = $converter->convertAsync(
filePath: 'documento.odt',
outputFormat: 'pdf',
outPath: 'salida.pdf',
mode: 'file' );
if ($result->isFile() && $result->hasOutputPath()) {
echo "OK: {$result->outputPath}\n";
} La conversión devuelve el contenido codificado en base64 dentro del resultado.
$result = $converter->convertAsync(
filePath: 'documento.odt',
outputFormat: 'pdf',
mode: 'stream' );
if ($result->isStream() && $result->hasBase64Content()) {
file_put_contents( 'salida.pdf', base64_decode($result->base64Content) );
}| Modo | Ventaja principal | Ideal para |
|---|---|---|
file |
Unoserver genera el archivo final en disco | Reportes grandes, workflows de almacenamiento |
stream |
Resultado en memoria para postprocesado inmediato | Procesamiento dinámico, APIs, respuestas HTTP |
En el directorio examples encontrarás scripts de ejemplo:
examples/example.phpexamples/test.php
Para ejecutarlos:
php examples/example.php
# o
php examples/test.phpAsegúrate de tener Unoserver corriendo en los puertos configurados en cada ejemplo.
El sistema monitorea automáticamente la salud de los servidores Unoserver:
- verifica la disponibilidad cada N segundos
- marca servidores como no saludables después de X fallos
- reintenta conexiones después de un período de timeout
- distribuye carga solo entre servidores saludables
- Usa
mode: 'file'cuando quieras que Unoserver genere el archivo final directamente. - Usa
mode: 'stream'cuando quieras recibir el contenido en memoria. - Mantén múltiples instancias de Unoserver si esperas alta concurrencia.
- Configura correctamente los directorios de salida y permisos de escritura.
- Prefiere
filepara documentos grandes si no necesitas procesarlos en memoria.
UnoserverXmlRpcClient encapsula:
- conexión por socket
- envío HTTP/XML-RPC
- lectura de respuesta
- validación de faults XML-RPC
- extracción del contenido de respuesta
UnoserverLoadBalancer encapsula:
- selección de servidor
- reintentos
- métricas de ejecución
- coordinación con
ServerHealthMonitor
ServerHealthMonitor se encarga de mantener actualizado el estado de los servidores disponibles.
Las contribuciones son bienvenidas. Por favor:
- Haz fork del repositorio
- Crea una rama para tu feature
- Haz commit de tus cambios
- Push a la rama
- Abre un Pull Request
Este proyecto está bajo la Licencia MIT.