Preguntas frecuentes
Lo que más se pregunta sobre instalación, licencias, uso y soporte de FoxServer. Las respuestas describen la versión publicada, la 0.9.38.
¿Cuáles son los requisitos del sistema?
Windows 10 o superior (de 32 o de 64 bits) y el runtime de .NET 10 en su variante x86. El de 64 bits no sirve, aunque esté instalado: FoxServer es de 32 bits porque carga el COM de Visual FoxPro, que lo es. Hacen falta permisos de administrador para instalar. Visual FoxPro solo se necesita en la máquina donde desarrollas.
¿Puedo correr FoxServer en Linux o macOS?
No, y no está planificado. El host carga el COM de Visual FoxPro, que es de Windows y de 32 bits, así que no es una cuestión de portar el código: es que el motor que se publica es VFP. Lo que sí puedes hacer es poner FoxServer detrás de cualquier proxy inverso.
¿Necesito tener VFP instalado en el servidor de producción?
No. El IDE de Visual FoxPro solo hace falta en la máquina donde desarrollas los controladores, porque init, controller-add y build delegan en un vfp9.exe. En el servidor basta con copiar junto a la DLL de tu aplicación los ficheros del runtime de VFP 9 (vfp9t.dll, vfp9r.dll, vfp9renu.dll y msvcr71.dll) y tener el runtime de .NET 10 de 32 bits.
¿Qué es exactamente una licencia Developer?
La que se vende por asientos, y solo sirve para desarrollar: el servidor responde 403 a toda petición que no venga de 127.0.0.1. Para que otra máquina llame a tu API hace falta una licencia Runtime, que es el otro producto de la tienda. Es el malentendido número uno: parece un problema de permisos y es la licencia.
¿Cómo activo mi licencia?
Descargas el fichero foxserver.lic desde el detalle de tu licencia en el portal y lo copias a la carpeta config de la instalación, que por defecto es C:\Programas\FoxServer\config\foxserver.lic (hasta la 0.9.34, C:\Program Files (x86)\FoxServer). Reinicias FoxServer. No hace falta internet.
¿Qué diferencia hay entre la compra y el mantenimiento?
La compra te da una licencia perpetua: la versión que compras funciona para siempre, y eso no cambia. Lo que acota el mantenimiento es el derecho a las versiones nuevas, y el portal lo aplica al descargar: te ofrece la última versión a la que tienes derecho, no la última que haya. Si ninguna build entra en tu período, la descarga responde 403 con el motivo.
¿FoxServer necesita internet para operar?
No. La licencia se valida en local contra una clave pública que va dentro del binario. No hay llamadas a servidores externos ni al instalar ni en marcha, y no hay telemetría.
¿Puedo correr varios servidores en la misma máquina?
Sí. Cada proyecto tiene su manifiesto en config\servers\ y su puerto. Todos se levantan cuando arranca FoxServer. Antes de añadir uno conviene comprobar que no haya otro con la misma clave host:puerto:prefijo: foxserver deploy lo comprueba y sale con 11 si choca, porque si no el host levanta uno y omite el otro con un aviso que solo se ve en el log.
¿Cómo configuro HTTPS?
Con un certificado en formato .pfx y las claves issecure, certificatename y certificatepassword del manifiesto. La contraseña se guarda cifrada con foxserver middleware-set, como todos los secretos: el manifiesto no lee variables de entorno, y un secreto en claro hace que el motor responda 500.
¿Cómo protejo mis endpoints con JWT?
Activas auth en el manifiesto. Todo endpoint que no lleve la palabra public en su HELP queda protegido. El endpoint de login es distinto: el token lo emite el middleware cuando tu controlador responde con la cabecera X-Auth-Status y un data con id, name y role. El contrato entero está en la página de Middleware.
¿Cómo manejo los errores en mis controladores?
Con los resultados que trae ApiController: this.BadRequest(mensaje, codigo), this.NotFound(mensaje), this.Forbidden(...) o this.Fail(estado, mensaje, codigo). Salen como Problem Details (RFC 9457), con application/problem+json, y tu mensaje viaja en detail. El middleware de registro los apunta solo; para lo demás tienes LogWarning, LogError y LogFromException.
¿Cuántas peticiones concurrentes aguanta?
Lo que manda no es el semáforo interno de 50, sino el pool de hilos STA de VFP: un hilo por núcleo, con un mínimo de 2 y un máximo de 8, POR SERVIDOR. Y cada hilo es un entorno VFP entero, con su lifecycle y sus conexiones: con tres manifiestos en una máquina de 16 núcleos son 24 entornos de VFP y otras tantas conexiones a la base de datos. La llamada a VFP es síncrona, así que un endpoint lento ocupa su hilo mientras dura, y si se pasa de su plazo el watchdog contesta 503. Se ajusta con FOXSERVER_WORKERS.
Vengo de la 0.8: ¿dónde está la DLL Interop?
Ya no hace falta. Hasta la 0.8 el motor cargaba un ensamblado Interop generado con TlbImp; desde la 0.9 activa tu código por ProgID directamente desde la MTDLL, y el dllpath del manifiesto apunta a esa MTDLL nativa. Si tu proyecto todavía trae su Interop, sigue sirviendo de respaldo por si el ProgID no estuviera registrado: no hay que borrar nada ni hay prisa por migrar.
¿Hay recarga en caliente?
Automática no: FoxServer no vigila el disco. Lo que hay es un interruptor, y basta. Después de recompilar con foxserver build, un POST al endpoint de estado con /reload y la cabecera X-Status-Pin suelta los objetos COM del servidor, y la siguiente petición los crea limpios con tu DLL nueva.
¿Puedo instalar FoxServer como servicio de Windows?
Sí, y el instalador ya lo hace por ti. A mano: bin\FoxServer.Host.exe --install-service, desde una consola elevada. Desde services.msc puedes configurar el inicio automático y el reinicio ante fallos. El servicio sirve los manifiestos de config\servers\ de la instalación, no los de un proyecto suelto.
¿Cómo envío webhooks a servicios externos?
No se disparan desde el código: se declaran. Con foxserver webhook-add-out registras la ruta, la URL del suscriptor y el secreto, y al servir ese endpoint el cuerpo de la respuesta sale firmado. FoxServer implementa Standard Webhooks, con firma v1,<base64 del HMAC-SHA256>, reintentos configurables y cola de fallidos. Lo pruebas con foxserver webhook-test.
¿Dónde están los logs?
Los de peticiones, en la carpeta de logging.path, con el nombre {fileprefix}_{Tipo}_{yyyyMMdd}.log. El del host es otro: logs\FoxServer_<fecha>.log en la raíz de la instalación, uno por día, partido a los 10 MB y purgado a los 30. El Visor de Eventos de Windows no recibe nada, ni siquiera en modo servicio: allí solo se escribe si falla la escritura del propio log.
¿Qué pasa cuando caduca la prueba de 30 días?
Compras una licencia de 1, 4 u 8 asientos y copias el .lic nuevo en config\. Tu código y tu configuración no cambian. Si necesitas servir a otras máquinas, la que te hace falta es una Runtime, no un asiento más.
¿Hay prueba o devolución?
Hay una licencia Trial gratuita de 30 días para evaluar, que sale del propio portal al verificar tu correo. Y si después de comprar no te sirve, la política de reembolso da 30 días desde la compra, por encima del derecho de desistimiento de 14 días que te corresponde por ley.
¿Cómo consigo soporte?
Escribiéndome a soporte@irwinrodriguez.dev. No hay foros ni repositorio público de incidencias: lo lees tú y lo leo yo, que es lo que hay cuando el producto lo hace una persona.
¿Puedo lanzar una tarea larga en segundo plano y responder después?
Dentro de una petición no hay paralelismo: el endpoint ocupa su hilo hasta que devuelve, y si pasa de
requesttimeoutseconds (120 s por defecto) el watchdog contesta 503. Para tareas de segundos, espera y responde. Para las largas, lo que hace la industria es la petición-respuesta asíncrona: el endpoint apunta el trabajo en una tabla de tareas, devuelve 202 Accepted con un identificador y una cabecera Location hacia /tareas/{id}, y el cliente pregunta ahí hasta que el estado sea «terminada». El trabajo lo hace otro proceso, no FoxServer: un ejecutable de VFP que vigile esa tabla, o FoxCore.Runtime. FoxServer no tiene hoy dónde ejecutar código después de responder, y está apuntado como decisión pendiente.¿Cómo depuro un controlador que devuelve 500?
Dentro del host no se puede: la MTDLL corre con el runtime de VFP, que no lleva depurador, así que
SET STEP ON ahí no hace nada. Para eso está FoxServerBench (FoxForge › Proyecto actual › Banco de pruebas): ejecuta tu procedure sin MTDLL, sin servidor y sin http.sys, con req y res rellenos como los rellenaría el motor, y el depurador abierto sobre tu fuente. Es un banco, no un emulador: no pasa por middlewares ni por la autenticación. Está en el paso 8 de la guía del paquete, y JSONFox.fxp tiene que estar en build\ para que req.json se rellene.¿Puedo crear un objeto una vez y reutilizarlo en todas las peticiones?
Sí: para eso existe el ApplicationLifecycle. Una clase
olepublic derivada de ApplicationLifecycle, en un .prg del proyecto; en OnApplicationStarting creas la conexión y la guardas con this.SetResource("db", loConexion), y en cualquier endpoint la recuperas con this.GetGlobalResource("db"), que devuelve .NULL. si no está. El hook rellena el bloque lifecycle del manifiesto al compilar. Desde la 0.9.16 corre una vez por hilo del pool, no por petición: con cuatro hilos tendrás cuatro conexiones, que es lo correcto en VFP. La receta completa está en el RECETARIO del paquete, §2.¿No encuentras tu respuesta? Escríbeme