embedded

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 4, 2026 License: MIT Imports: 1 Imported by: 0

README

🎫 Ticket Daemon

Language Platform License WebSocket

Ticket Daemon es un Servicio de Windows diseñado para entornos de producción retail. Actúa como un middleware robusto que conecta aplicaciones Web POS con impresoras térmicas físicas mediante WebSocket.

El servicio gestiona la concurrencia de multiples terminales, encola trabajos para garantizar el orden de impresión y utiliza la librería Poster como motor de renderizado ESC/POS.

✨ Características Principales

  • 🔌 Servidor WebSocket de alto rendimiento (puerto 8766 por defecto).
  • 🛡️ Protección de Backpressure: Cola con buffer (100 slots) y rechazo inmediato si se satura.
  • 🖨️ Servicio Nativo Windows: Integración completa con SCM (Service Control Manager).
  • 📝 Logging Estructurado: Rotación automática de archivos (5 MB) para mantenimiento cero.
  • 🖨️ Motor Poster: Soporte avanzado para texto, códigos de barras, QR e imágenes.

🏗️ Arquitectura del Sistema

Estructura de Componentes

El siguiente diagrama ilustra como el servicio envuelve los servidores HTTP/WS y coordina el flujo hacia el hardware.

graph TD
    classDef go fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#000;
    classDef data fill:#fff3e0,stroke:#e65100,stroke-width:2px,color:#000;
    classDef hw fill:#f3e5f5,stroke:#4a148c,stroke-width:2px,color:#000;

    subgraph Host["Host del Servicio Windows"]
        direction TB
        Service[Wrapper del Servicio]:::go -->|Init/Start| HTTP[Servidor HTTP]:::go
        Service -->|Start/Stop| Worker[Worker de Impresion]:::go
        HTTP -->|/ws| WSServer[Handler WebSocket]:::go
    end

    subgraph Flow["Flujo de Datos"]
        direction TB
        Client[Cliente Web POS]:::data <-->|JSON Messages| WSServer
        WSServer -->|Push Job| Queue[Canal Buffer 100]:::data
        Queue -->|Pop Job| Worker
    end

    subgraph Hardware["Integracion de Hardware"]
        direction TB
        Worker -->|Execute| PosterLib[Libreria Poster]:::hw
        PosterLib -->|Bytes ESC/POS| Spooler[Spooler de Windows]:::hw
        Spooler -->|USB/Serial/LPT| Printer[Impresora Termica]:::hw
    end
Modelo de Concurrencia (Fan-In)

El sistema utiliza un patron de Fan-In con un Select no bloqueante. Esto permite manejar multiples conexiones simultáneas sin bloquear el hilo principal si la impresora es lenta.

graph TB
    classDef client fill: #e8f5e9, stroke: #2e7d32, stroke-width: 2px;
    classDef logic fill: #fff9c4, stroke: #fbc02d, stroke-width: 2px;
    classDef crit fill: #ffebee, stroke: #c62828, stroke-width: 2px;
    classDef core fill: #e3f2fd, stroke: #1565c0, stroke-width: 2px;
    subgraph Clients["Capa HTTP/WS Concurrente"]
        C1[Cliente POS 1]:::client --> H1[Goroutine Handler 1]:::core
        C2[Cliente POS 2]:::client --> H2[Goroutine Handler 2]:::core
        C3[Cliente POS 3]:::client --> H3[Goroutine Handler 3]:::core
    end

    subgraph Sync["Sincronizacion"]
        direction TB
        H1 & H2 & H3 --> Select{Select Non-blocking}:::logic
        Select -- " Default Lleno " --> Overflow[Error: Cola Llena]:::crit
        Select -- " Case Send " --> Channel[Canal cap=100]:::core
    end

    subgraph Process["Procesamiento Serial"]
        Channel --> WLoop[Worker Loop]:::core
        WLoop --> Mutex[Poster Executor]:::core
        Mutex --> Hardware[Hardware Fisico]:::crit
    end
Ciclo de Vida del Mensaje
sequenceDiagram
    participant C as Cliente Web
    participant H as WS Handler
    participant Q as Cola Canal
    participant W as Worker
    participant P as Poster Engine
    Note over C, H: Conexion establecida ws://...
    C ->> H: {"tipo":"ticket", "datos":{...}}

    rect rgb(240, 248, 255)
        Note right of H: server.go
        H ->> H: Validar JSON

        alt Cola Llena (Select Default)
            H -->> C: {"tipo":"error", "mensaje":"Cola llena, reintente"}
        else Encolado Exitoso
            H ->> Q: Push PrintJob
            H -->> C: {"tipo":"ack", "status":"queued", "pos": 5}
        end
    end

    rect rgb(255, 248, 240)
        Note right of W: processor.go
        Q ->> W: Pop PrintJob
        W ->> P: Execute(Document)

        alt Exito
            P -->> W: nil
            W ->> H: NotifyClient(Success)
            H -->> C: {"tipo":"result", "status":"success"}
        else Error
            P -->> W: error
            W ->> H: NotifyClient(Error)
            H -->> C: {"tipo":"result", "status":"error", "mensaje":"... "}
        end
    end

📡 Protocolo WebSocket

Endpoints
Endpoint Descripcion
ws://localhost:8766/ws Conexion WebSocket
http://localhost:8766/health Health check (JSON)
http://localhost:8766/ Cliente de prueba HTML
Tipos de Mensaje
Direccion tipo Descripcion
C -> S ticket Enviar trabajo de impresion
C -> S status Solicitar estado de la cola
C -> S ping Ping al servidor
C -> S get_printers Listar impresoras instaladas
S -> C ack Trabajo aceptado y encolado
S -> C result Trabajo completado/fallido
S -> C error Error de validacion/cola
S -> C printers Lista de impresoras
Ejemplo de Payload
{
  "tipo": "ticket",
  "id": "pos1-20260109-001",
  "datos": {
    "version": "1.0",
    "profile": {
      "model": "80mm EC-PM-80250",
      "paper_width": 80
    },
    "commands": [
      {
        "type": "text",
        "data": {
          "content": {
            "text": "TICKET DE PRUEBA",
            "align": "center",
            "content_style": {
              "bold": true,
              "size": "2x2"
            }
          }
        }
      },
      {
        "type": "cut",
        "data": {
          "mode": "partial"
        }
      }
    ]
  }
}
Descubrimiento de Impresoras

El servicio detecta automáticamente las impresoras instaladas en Windows al iniciar y expone esta información via WebSocket y HTTP.

Mensaje WebSocket:

Petición para obtener impresoras:

{
  "tipo": "get_printers"
}

Respuesta del servidor:

{
  "tipo": "printers",
  "status": "ok",
  "printers": [
    {
      "name": "58mm PT-210",
      "port": "USB001",
      "driver": "Generic / Text Only",
      "status": "ready",
      "is_default": true,
      "is_virtual": false,
      "printer_type": "thermal"
    }
  ],
  "summary": {
    "status": "ok",
    "detected_count": 5,
    "thermal_count": 1,
    "default_name": "58mm PT-210"
  }
}

Health Check (/health):

{
  "status": "ok",
  "printers": {
    "status": "ok",
    "detected_count": 5,
    "thermal_count": 1,
    "default_name": "58mm PT-210"
  }
  // ... other fields
}
Estado Printers Significado
ok Al menos una impresora térmica detectada
warning Hay impresoras físicas pero ninguna es térmica
error No hay impresoras físicas instaladas

Nota: El estado ready refleja el último estado conocido del Windows Spooler. Para impresoras USB/Serial, esto puede no reflejar si están físicamente conectadas en tiempo real.


⚙️ Configuración (Build-Time)

La configuración se inyecta al compilar para garantizar inmutabilidad en producción.

Ambiente Flag Puerto Log Verbose Servicio
Produccion prod 8766 (0.0.0.0) false TicketServicio
Test/Dev test 8766 (localhost) true TicketServicioTest

Para modificar los valores predeterminados, edite internal/daemon/program.go antes de compilar.


🚀 Inicio Rápido

Prerrequisitos
  • Go 1.24+
  • Task (go-task) - Instalación
  • Windows 10/11 o Windows Server
Comandos Comunes (con Task)
# Ver todos los comandos disponibles
task

# Compilar y ejecutar en modo consola (desarrollo)
task run

# Compilar ejecutable standalone (doble-clic para ejecutar)
task build-console

# Instalar como Servicio de Windows (requiere Admin)
task install

# Ver logs en tiempo real
task logs

# Abrir dashboard de diagnostico
task open

# Verificar estado del servicio
task status
Ejecutable Standalone (Sin Task)

Si prefieres distribuir solo el .exe:

# 1. Compilar
task build-console

# 2. El ejecutable queda en: 
#    bin/TicketDaemon_Console.exe

# 3. Doble-clic para ejecutar, o desde terminal:
.\bin\TicketDaemon_Console.exe

# 4. Abrir navegador en: http://localhost:8766

📂 Estructura del Proyecto

ticket-daemon/
├── api/
│   └── v1/
│       ├── DOCUMENT_V1.md        # Especificacion formato documento
│       ├── WEBSOCKET_V1.md       # Especificacion protocolo WebSocket
│       ├── document.schema.json  # JSON Schema del documento
│       └── websocket.schema.json # JSON Schema mensajes WS
│
├── cmd/
│   └── TicketServicio/
│       └── ticket_servicio.go    # Punto de entrada (main)
│
├── examples/
│   └── json/                     # Ejemplos de documentos JSON
│       ├── showcase.json         # Demo de todos los comandos
│       └── table_showcase.json   # Ejemplos de tablas
│
├── internal/
│   ├── assets/
│   │   ├── embed.go              # Go embed para archivos web
│   │   └── web/                  # Dashboard HTML/CSS/JS embebido
│   │
│   ├── daemon/
│   │   ├── program.go            # Wrapper svc.Service y Configuracion
│   │   ├── logger.go             # Logging filtrado con rotacion
│   │   ├── daemon_types.go       # Tipos de respuesta Health
│   │   └── printer_discovery.go  # Descubrimiento de impresoras Windows
│   │
│   ├── printer/
│   │   └── printer_types.go      # Tipos compartidos de impresora
│   │
│   ├── server/
│   │   ├── server.go             # Logica WebSocket y Cola (Select)
│   │   └── clients.go            # Registro Thread-Safe de clientes
│   │
│   └── worker/
│       └── processor.go          # Integracion con libreria Poster
│
├── go.mod
├── Taskfile.yml                  # Automatizacion de tareas
├── README.md
└── LEARNING.md                   # Resumen tecnico para portfolio

📝 Logs y Auditoria

Los logs se escriben en %PROGRAMDATA% y rotan automáticamente al superar 5 MB.

Ambiente Ruta Tipica
Prod C:\ProgramData\TicketServicio\TicketServicio.log
Test C:\ProgramData\TicketServicioTest\TicketServicioTest.log
Ver Logs
# Ultimas 100 lineas
task logs

# O directamente:
Get-Content "C:\ProgramData\TicketServicioTest\TicketServicioTest.log" -Tail 100 -Wait

🔧 Solución de Problemas

El servicio no inicia
# Verificar estado
sc query TicketServicioTest

# Ver logs de error
task logs

# Reinstalar
task uninstall
task install
No se puede conectar por WebSocket
  1. Verificar que el servicio esté corriendo: task status
  2. Verificar firewall para puerto 8766
  3. Probar health check: task health
La impresora no imprime
  1. Verificar nombre exacto en profile.model (debe coincidir con Windows)
  2. Verificar que Print Spooler este activo: Get-Service Spooler
  3. Probar impresión directa desde Windows

📄 Licencia

MIT © adcondev - RED 2000


📖 Documentación de la API

Este proyecto incluye documentación detallada del protocolo y formato de documentos:

Documento Descripción
DOCUMENT_V1.md Especificación del formato de documento de impresión
WEBSOCKET_V1.md Especificación del protocolo WebSocket
document.schema.json JSON Schema para validación de documentos
websocket.schema.json JSON Schema para mensajes WebSocket
Ejemplos de Uso

La carpeta examples/json/ contiene documentos de ejemplo listos para usar:

  • showcase.json - Demostración de todos los tipos de comandos
  • table_showcase.json - Ejemplos de tablas con diferentes configuraciones
  • ticket_service_test.json - Ticket completo con impuestos y QR

🔗 Recursos Relacionados

Documentation

Index

Constants

This section is empty.

Variables

View Source
var WebFiles embed.FS

WebFiles contiene el sitio web estático (HTML, CSS, JS)

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd
TicketServicio command
Package main es el punto de entrada del Ticket Daemon.
Package main es el punto de entrada del Ticket Daemon.
internal
daemon
Package daemon contiene la lógica del servicio de Windows.
Package daemon contiene la lógica del servicio de Windows.
printer
Package types contains shared types to avoid import cycles.
Package types contains shared types to avoid import cycles.
server
Package server maneja las conexiones WebSocket y el encolamiento de trabajos.
Package server maneja las conexiones WebSocket y el encolamiento de trabajos.
worker
Package worker contiene la lógica del procesador de trabajos de impresión.
Package worker contiene la lógica del procesador de trabajos de impresión.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL