IR
irwinrodriguez.dev
Volver a documentacion

Funciones avanzadas

FoxServer incluye funcionalidad avanzada para casos de uso modernos: streaming de eventos en tiempo real, webhooks con reintentos, recarga en caliente de controladores, metricas y modo servicio de Windows.

Server-Sent Events (SSE)

SSE permite que el servidor empuje eventos al cliente a traves de una conexion HTTP persistente. Ideal para notificaciones en tiempo real, progreso de operaciones largas y feeds de datos.

Habilitar en JSON:

{ "middleware": { "sse": true } }

Implementacion en el controlador:

PROCEDURE GetLiveData(req, res) HELP "GET: stream/live public"
    LOCAL i, lcData

    res.header("Content-Type",  "text/event-stream")
       .header("Cache-Control", "no-cache")
       .header("Connection",    "keep-alive")

    FOR i = 1 TO 20
        lcData = '{"tick":' + TRANSFORM(i) + ',"ts":"' + DTOC(DATETIME()) + '"}'
        res.send("data: " + lcData + CHR(13) + CHR(10) + CHR(13) + CHR(10))
        INKEY(1)   && 1-second pause between events
    NEXT
ENDPROC

Cliente JavaScript:

const es = new EventSource('/api/stream/live');
es.onmessage = (e) => {
  const data = JSON.parse(e.data);
  console.log('tick', data.tick, 'at', data.ts);
};
es.onerror = () => es.close();

Sistema de Webhooks

FoxServer incluye un procesador de webhooks con cola persistente, reintentos automaticos con backoff exponencial y firma HMAC-SHA256.

  • Cola persistente (sobrevive a reinicios del servidor)
  • Reintentos automaticos con backoff exponencial configurable
  • Firma automatica HMAC-SHA256 en cada entrega
  • Workers concurrentes para entregas paralelas
  • Log de todos los intentos de entrega

Configuracion:

"middleware": {
  "webhooks": {
    "enabled": true,
    "global": {
      "retries": 3,
      "timeout": 30,
      "backoff": [5, 15, 30],
      "queue": { "path": "queue/webhooks", "workers": 2 },
      "logging": { "enabled": true, "path": "logs/webhooks/" }
    }
  }
}

Disparar un webhook desde un controlador:

PROCEDURE PostOrder(req, res) HELP "POST: orders public"
    LOCAL lcOrderId, loEvt, loResp

    lcOrderId = THIS.CreateOrder(req.json)

    * Build the webhook event
    loEvt = THIS.newObject("event,data")
    loEvt.event      = "order.created"
    loEvt.data       = THIS.newObject("orderId,customer,total")
    loEvt.data.orderId   = lcOrderId
    loEvt.data.customer  = req.json.customer
    loEvt.data.total     = req.json.total

    * Queue — FoxServer handles delivery, retries, signing
    THIS.QueueWebhook("https://partner.com/webhooks", "shared-secret", loEvt)

    loResp = THIS.newObject("orderId,status")
    loResp.orderId = lcOrderId
    loResp.status  = "created"
    res.status(201).json(THIS.ToJson(loResp))
ENDPROC

El receptor recibe:

POST https://partner.com/webhooks
webhook-id: 550e8400-e29b-41d4-a716-446655440000
webhook-timestamp: 2026-04-11T14:23:45Z
webhook-signature: sha256=hmac-sha256-of-body

{
  "event": "order.created",
  "data": { "orderId": "ORD-001", "customer": "Irwin", "total": 99.99 }
}

Hot Reload

Hot Reload detecta cambios en el DLL compilado y recarga los controladores sin reiniciar el servidor. Las peticiones en vuelo terminan en la version anterior; las nuevas peticiones usan la version actualizada.

Como funciona:

  1. Edita y guarda tu archivo .prg en VFP.
  2. WinFx o el compilador VFP regenera el DLL Interop.
  3. FoxServer detecta el cambio en el archivo DLL (FileSystemWatcher).
  4. Espera a que las peticiones activas terminen (graceful drain).
  5. Libera referencias COM a los controladores viejos.
  6. Carga el nuevo DLL en un AppDomain aislado.
  7. Registra: 'Hot reload complete'.

Habilitar en JSON:

{
  "hotreload": {
    "enabled": true,
    "watchpaths": ["C:\\projects\\myapi\\build"],
    "excludepatterns": ["*.log", "*.tmp"]
  }
}

Metricas del servidor

El endpoint /status (cuando esta habilitado) devuelve el estado actual del servidor incluyendo metricas de rendimiento.

GET /status
{
  "status": "ok",
  "version": "0.7.0",
  "license": "Commercial",
  "uptime": "5d 3h 22m",
  "totalRequests": 182043,
  "successRequests": 181998,
  "errorRequests": 45,
  "avgResponseMs": 12,
  "activeConnections": 7,
  "memoryMB": 245
}

Acceder a metricas desde un controlador:

PROCEDURE GetStatus(req, res) HELP "GET: status public"
    LOCAL loMetrics, loResp
    loMetrics = THIS.GetServerMetrics()
    loResp = THIS.newObject("status,metrics")
    loResp.status  = "ok"
    loResp.metrics = loMetrics
    res.status(200).json(THIS.ToJson(loResp))
ENDPROC

White Label

Permite ocultar que el servidor esta construido con FoxServer. Util cuando distribuyes un producto bajo tu propia marca.

{
  "whitelabel": {
    "serverName": "Acme API Gateway",
    "headerTitle": "Acme Corp",
    "hideVersion": true
  }
}

Modo Servicio de Windows

FoxServer puede instalarse como un Servicio de Windows para arranque automatico y ejecucion en segundo plano sin ventana de consola.

Comandos:

# Install as service
FoxServer.exe --install-service --name "AcmeAPIServer"

# Uninstall service
FoxServer.exe --uninstall-service --name "AcmeAPIServer"

# Manage via Windows Services
services.msc
En modo servicio, los logs se escriben en el Visor de Eventos de Windows (Application) ademas de los archivos de log configurados.

Siguiente: Referencia API →