xrt 2.0 · 310 620 строк собственного рантайма · MIT

Один исполняемый файл —
весь C-серверный мир

XServer упаковывает собственные TLS, движок конкурентности и компилятор TCC в один exe — ваше приложение это просто каталог исходников на C, компилируемых в машинный код прямо в процессе, с горячей перезагрузкой без простоя после каждого изменения. Без интерпретатора, без FFI, без внешних зависимостей.

0мкс
Задержка запроса10 маршрутов · одно соединение
0
API доступны из скриптовполный экспорт xrt
0
Внешние зависимостибез OpenSSL / без DLL
0МБ
Размер одного файлакомпилятор и SDK внутри
XServer — deploy
Исходники приложения компилируются встроенным TCC в нативный код — вывод здесь это настоящий лог
возможности

Создан для многолетней работы —
нативная C-серверная платформа

Протоколы, криптография, конкурентность, отладка — всё написано самостоятельно и встроено. Не привязано, а упаковано в тот же файл.

Доставка одним файлом

Один xs.exe плюс каталог исходников на C — это полное развёртывание. Компилятор TCC, полный набор заголовков SDK и системные библиотеки встроены в VFS со сжатием LZMA — на целевой машине ничего устанавливать не нужно.

C как скрипт

devfile компилируется встроенным TCC прямо в процессе в машинный код и вызывает 3057 API хоста напрямую через таблицу символов — ни интерпретатора, ни накладных расходов FFI.

Горячая перезагрузка без простоя

Правите C-код — изменения вступают в силу мгновенно: все кандидаты сначала компилируются, замена происходит только при успехе; при провале старое поколение продолжает обслуживать, а после обнуления ссылок его безопасно забирает GC-поток.

Собственный TLS 1.2 / 1.3

Без зависимости от OpenSSL: X25519 / P-256 / P-384, AES-GCM, ChaCha20-Poly1305, возобновление сессий, проверка цепочек X.509 и CRL — и на серверной, и на клиентской стороне.

Мультипротокольные драйверы

http / https, ws / wss, tcp / tcps и udp имеют единый жизненный цикл; vhost, выбор сертификатов по SNI, статический слой и перехват соединений встроены.

Движок высокой конкурентности

IOCP / epoll / kqueue / io_uring / select — пять бэкендов событийного цикла, плюс пул потоков с вытеснением, корутины, каналы и future.

Встроенная отладка памяти

Канарейки / изоляция UAF / инъекция отказов / кольцевой журнал событий / отчёты об утечках в TEXT и JSON — включается прямо в продакшн-процессе, отдельная сборка не нужна.

Настраиваемые расширения

Одиннадцать опциональных библиотек (sqlite / почтовое семейство / LLM / Markdown / сертификаты… всего 700 символов) вкомпилируются по мере надобности или все сразу одним ключом; новое расширение — это одна json-запись плюс import-таблица, без изменения кода хоста.

Форма настольного приложения

Расширение webview + узел class: "app" = локальный HTTP + окно WebView2; вместе с односоставной публикацией xs pack продукт — настольный exe по двойному щелчку. Без среды автоматически headless.

Автопродление сертификатов

Встроенный демон ACME: продление DNS-01 за 30 дней до истечения + горячая замена (соединения не рвутся); цепочка отказоустойчивости directories[] — Let's Encrypt недоступен, идём в litessl, при восстановлении возвращаемся.

Модель доверия: скрипты — доверенный нативный код (без песочницы), для развёртываний под контролем оператора — все возможности открыты, границу определяете вы.

горячая перезагрузка

Строка на C изменена — мир переключается бесшовно

Горячая перезагрузка — это координатор целевого состояния: неизменяемый снимок → полная прекампиляция → атомарная публикация → два поколения параллельно → утилизация при нуле ссылок.
Нескомпилировавшийся кандидат отклоняется целиком — откат это семантическая гарантия, а не средство спасения.

XServer — live reload
  1. Неизменяемый снимок Конфигурация и исходники скриптов замораживаются в отпечаток revision — все серверы одной перезагрузки видят одно и то же входное состояние.
  2. Полная прекампиляция Всё множество скриптов-кандидатов сервера обязано скомпилироваться до побочных эффектов — любая неудача отклоняет всю партию.
  3. Атомарная публикация Слоты прослушивания переключаются без мерцания: неизменённые эндпоинты передаются на месте, новые соединения сразу попадают в новое поколение.
  4. Два поколения параллельно Старые соединения дорабатывают на старом коде до конца; ServiceSwap → xsSwapTake передаёт живое состояние.
  5. Утилизация при нуле ссылок Когда lease обнуляется, GC-поток в правильном порядке разрушает скрипт, драйвер и конфигурацию — в soak-тестах ноль утечек и ноль падений.
слияние намерений latest-wins pending ≤ 64 горячая замена сертификатов таймеры умирают со своим поколением 4 протокола × TLS
код

Никакой магии, только C

Примеры ниже — реальный код из репозитория. XServer не навязывает объектную модель — вы работаете с нативными структурами xrt напрямую; компилятор и система типов и есть ваш фреймворк.

/* route.h — слотная регистрация URI × метод (фрагмент реального кода) */
static void RouteHTTP_Init(void)
{
	G_StaticRouteTableHTTP = xrtMapCreate(sizeof(RouteInfoHTTP));

	/* Статические маршруты: точные URI */
	AddStaticRouteHTTP("/api/v1/items", XHTTP_METHOD_GET,  Handle_API_List);
	AddStaticRouteHTTP("/api/v1/items", XHTTP_METHOD_POST, Handle_API_Add);

	/* Динамические маршруты: захват сегмента {id},
	   маски методов свободно комбинируются */
	AddDynamicRouteHTTP("/api/v1/items/{id}",
		XHTTP_METHOD_GET,                    Handle_API_Item);
	AddDynamicRouteHTTP("/api/v1/items/{id}",
		XHTTP_METHOD_PUT | XHTTP_METHOD_PATCH, Handle_API_Item_Update);
	AddDynamicRouteHTTP("/api/v1/items/{id}",
		XHTTP_METHOD_DELETE,                 Handle_API_Item_Delete);

	/* После регистрации — однократная компиляция в неизменяемые
	   pattern; стоимость сопоставления не зависит от числа маршрутов */
	(void)RouteHTTP_Compile();
}
/* route_http/basic.h — построение JSON через xvalue (фрагмент реального кода) */
static void Handle_JSON(XS_HttpReq* pReq,
	const RouteParamHTTP* arrParam, uint32 iParamCount)
{
	const XS_HostInfo* pHost = pReq->host;
	xvalue* pObject = xrtValueObject();

	(void)arrParam; (void)iParamCount;
	xrtValueObjectSetNew(pObject, XRT_STR_LITERAL("server"),
		xrtValueString(XRT_STR_LITERAL("xs3 demo")));
	xrtValueObjectSetNew(pObject, XRT_STR_LITERAL("ok"),
		xrtValueBool(true));
	xrtValueObjectSetNew(pObject, XRT_STR_LITERAL("host"),
		xrtValueString(xrtStrView((pHost->Name ? pHost->Name : "?"))));

	(void)ReplyJSON(pReq, 200, pObject);
	xrtValueRelease(pObject);
}
/* Контрактные колбэки ws / wss: XServer делает рукопожатие и кадрирование,
   вы пишете только бизнес-логику */
static void WsOpen(XS_HostInfo* pHost, xwsstream* pWs)
{
	xrtWsStreamText(pWs, xrtStrView("connected"));
}

static void WsText(XS_HostInfo* pHost, xwsstream* pWs, xstrview tText)
{
	/* Маскирование, пересборка фрагментов, управляющие кадры и лимиты
	   сообщений полностью обрабатываются слоем xrt */
	(void)xrtWsStreamText(pWs, tText);          /* echo */
}

static void WsBinary(XS_HostInfo* pHost, xwsstream* pWs, xbytesview tData)
{
	xvalue* pMsg = xrtValueObject();
	xrtValueObjectSetNew(pMsg, XRT_STR_LITERAL("size"),
		xrtValueInt64((int64)tData.Size));
	(void)xrtWsStreamBinary(pWs, tData);
	xrtValueRelease(pMsg);
}
/* Передача состояния при горячей перезагрузке: старое поколение экспортирует
   снимок, новое забирает его и продолжает (контрактный API) */
static bool ServiceSwap(XS_HostInfo* pHost, xvalue** ppShared)
{
	xvalue* pState = xrtValueObject();

	xrtValueObjectSetNew(pState, XRT_STR_LITERAL("counter"),
		xrtValueInt64(G_iCounter));
	*ppShared = pState;               /* неразрушающий снимок: старое
	                                      поколение может продолжать */
	return true;
}

static void ServiceInit(XS_HostInfo* pHost)
{
	xvalue* pState = xsSwapTake(pHost);   /* действительно только внутри
	                                      Init нового поколения */

	if ( pState != NULL ) {
		G_iCounter = xrtValueInt64(
			xrtValueObjectGet(pState, "counter"));
		xrtValueRelease(pState);
	}
}

/* Запуск перезагрузки: координация целевого состояния; возвращённый
   стабильный ID позволяет узнать итог */
XS_ReloadId iId = xsReloadHostSubmit(pHost);
Скрипты напрямую вызывают 2957 API xrt: сеть · TLS · HTTP · WS · корутины · потоки · файлы · JSON · шаблоны · SQLite · XTP2 … Справочник API →
бенчмарк

В одной лиге с Go, плоско на десяти тысячах маршрутов

Замеры routebench: последовательные запросы по одному keep-alive-соединению, по 3 раунда × 10 000 на конфигурацию, пять стеков на одной машине.

0мкс
Задержка @ 10 маршрутов
0мкс
Задержка @ 10 000 маршрутов
+0%
Рост задержки на 10k маршрутовFastAPI за то же время +935%
0–0×
быстрее PHP / FastAPI на 10k маршрутов

10 маршрутов мкс / запрос (меньше — лучше)

XServer C/TCC
42.0
Go 1.22
42.2
PHP 8.3
391.6
FastAPI
379.0

10 000 маршрутов мкс / запрос (меньше — лучше)

Go 1.22
45.7
XServer C/TCC
59.1
PHP 8.3
2318.2
FastAPI
3920.1

Пакетная компиляция pattern и сопоставление, не зависящее от числа маршрутов, удерживают рост задержки на уровне +41% при 10k маршрутов; среди сравниваемых стеков FastAPI деградирует на +935%, PHP на +492%.

архитектура

Три слоя, один процесс, прямые вызовы

Никаких IPC и границ сериализации — скрипты вызывают хост по адресу через таблицу символов; вызов функции остаётся просто вызовом функции.

Ваш код · компиляция TCC · единица горячей перезагрузки
main.croute.hmodules/ route_http/page/template/wwwroot/
Приложение — это каталог исходников: 14 контрактных символов (ServiceInit / RequestProc / WsText …) и есть всё соглашение
Хост XServer · ~9 400 строк
Сборка конфигурацииДрайверы протоколов http·ws·tcp·udpТопология и поколения Координатор reloadДвижок скриптовvhost · SNI
Координация целевого состояния xs.json · передача слотов прослушивания без мерцания · GC поколений по счётчику ссылок
Рантайм xrt · 310 620 строк · 91 модуль · 3 030 API
TLS 1.2/1.3 + X.509HTTP/1.1WebSocket Событийный цикл на пяти бэкендахКорутины · пул потоков · каналы Контейнеры · JSON · шаблоны · regex · patternОтладка памяти
Ноль TODO в собственном коде · двухуровневая обрезка модулей (XRT_MODULE_* / XRT_FEATURE_*)
Встроенный TCC 0.9.28rc LZMA VFS · 350 ресурсов Windows / Linux 10 опциональных библиотек · all одним ключом · xs --version
развёртывание

Собрал один раз — скопировал и работает

Артефакт атомарно заменяется только после успешной линковки — неудачная сборка всегда оставляет последний рабочий xs.exe.

myapp/ всё развёртывание ≈ один exe + исходники
xs.exe            5,2 МБ   единственный бинарник
xs.json           сервисы · порты · TLS · vhost
main.c            точка входа приложения (ServiceInit)
route.h           реестр регистрации маршрутов
modules/           переиспользуемые модули (http/db/template…)
route_http/        обработчики запросов
page/              контролируемые страницы (вне wwwroot)
template/          шаблоны xrtTemplate
db/                файлы данных SQLite
wwwroot/           корень статики
01

Сборка

Одна команда собирает нужный вариант под обе платформы (Windows / Linux):

build.bat build.bat all
02

Копирование

Скопируйте xs.exe и каталог исходников на целевую машину — без установки рантайма, без DLL и заголовков; компилятор уже внутри exe.

03

Запуск и развитие

Старт — xs xs.json; дальше правите любой C-код и вызываете xsReloadHostSubmit() для горячей перезагрузки — без разрывов и простоя.

single-file deploy

Один exe — весь сайт внутри

xs.json, wwwroot, исходники на C и TLS-сертификаты упаковываются в один LZMA-архив, дописываемый в конец бинарника xs, — запуск без аргументов читает конфигурацию и отдаёт файлы прямо из пакета. Одноимённые файлы на диске всегда важнее: положите файл рядом с exe для горячего исправления, удалите — вернётся версия из пакета.

Однофайловая публикация в три шага
# 1. упаковка (в каталоге сайта должен быть xs.json; LZMA по элементам)
xs.exe pack site/ -o app.exe
# 2. развёртывание: скопировать этот один файл — и всё
app.exe
# 3. горячее исправление: одноимённый файл рядом с exe переопределяет пакет
echo ... > app.exe/wwwroot/index.html

Пакет — это всё

  • конфигурация + статика + исходники + сертификаты — всё в пакете; демо-сайт 1,7 МБ → 542 КБ
  • приоритет диска: внешние файлы всегда побеждают; положите продлённый сертификат рядом с exe — без перепаковки
  • встроенные инструменты: --list элементы / --extract распаковка / --strip обратно к исходному бинарнику
  • нулевая цена старта: проба читает последние 24 байта себя; неизменяемый индекс потокобезопасен, содержимое распаковывается лениво и остаётся в кэше
  • --no-vfs: сразу игнорировать пакет приложения, отладка в режиме каталогов
app node

Сервер и приложение

Объявите сервисный узел class: "app" в xs.json — локальный HTTP-сервис и окно WebView2 в одном процессе: окно загрузки при старте, автоматическое открытие интерфейса по готовности сервиса, корректная остановка при закрытии окна.

class: "app" в действии
Настольное окно узла app XServer: интерфейс сайта внутри окна WebView2

Одна конфигурация, две формы

  • class: "app": локальный HTTP + окно в одном; интерфейс — обычная веб-страница, шаблоны, маршрутизация и SQLite работают как обычно
  • автоматический запас: среды без WebView2 деградируют в headless-сервис, тот же бинарник без изменений
  • xsw.exe: вариант без консоли идёт в релизном пакете — двойной щелчок, и это настольное приложение
  • вместе с xs pack: сайт, исходники и сертификаты в одном exe — однофайловое распространение настольных приложений
  • доступен весь стек: диалоги xllm и оркестрация агентов xwork работают за окном
расширения

Нужно больше? Вкомпилируйте

Расширение = одна json-запись + import-таблица символов + заголовочный файл. Статически вкомпилируется в хост, символы экспортируются скриптам — доступны даже плагинам со вложенной компиляцией TCC.

sqlite

272 символа · FULLMUTEX-безопасность для worker'ов

Полный движок SQLite вкомпилирован статически, заголовок доступен через VFS. Prepared statements, привязка параметров, транзакции — REST CRUD демо построен на нём.

sqlite3_open_v2("db/main.db", &db, flags, NULL);

xtp2

кадровый протокол с 32-байтовым заголовком · потоковый парсер

Бинарный протокол прикладного уровня поверх упорядоченных потоков байтов: сообщения REQUEST / RESPONSE / PUSH / EVENT, полноценная система limits, проверен libFuzzer.

xtp2_feed(&st, buf, len);  /* инкрементальный разбор, ноль аллокаций */

xllm

53+45 символа · 3 диалекта · SSE-поток

Ядро вызова LLM (тот же источник, что extlibs xrt): конструирование запросов и мультимодальных part, диалекты Chat Completions / Responses / Anthropic, разбор SSE, повторы и отмена; сеть и TLS даёт xrt хоста.

xllmRequestAddTextMessage(&req, XLLM_ROLE_USER, "hi");

qrcodegen

10 символов · QR + PNG вывод

Генератор QR-кодов (Nayuki, MIT): кодирование и чтение модулей за один шаг; слой вывода PNG (1-битный grayscale, IDAT через zlib xrt) — готов для 2FA, платёжных кодов, API-маршрутов и вставки в письма.

png = qrcodegen_png(qr, 4, 4, &size);

xjwt

24 символа · HS/RS/ES + JWKS

Подпись и проверка JWT (RFC 7519): HS256/384/512, семейство RS (PKCS#8/PKCS#1), ES256 (DER, совместимость с OpenSSL), выбор ключей JWKS, кэш публичных ключей; код ошибки одной строкой, aud-массивы поддержаны.

claims = xjwtVerify(token, pem, &check);

xoauth2

25 символов · auth-code + PKCE + OIDC

Клиент OAuth 2.0 (RFC 6749): пять пресетов провайдеров, PKCE, обновление токенов, однократное сжигание state/nonce; транспорт через инъекцию колбэка (в комплекте TLS-реализация на xrt). Связь с xjwt — восемь строк клея для OIDC-логина.

tok = xoauth2CompleteLogin(&oauth, code, state);

xwork

42 символа · оркестрация агентов

Вершина AI-стека (над xllm): регистрация и выполнение инструментов, политика рабочей области, типы субагентов, поток уведомлений и планирование компакции. Подтверждено сквозным agent-demo — шлюзы утверждения, трассы и diff-панели проверены в браузере.

xworkAgentRegisterBuiltinTools(agent);

webview

узел app · окно рабочего стола

Окно WebView2 + сервисный узел class: "app": загрузочный сплэш → авто-открытие при готовности → корректная остановка при закрытии. Вместе с односоставной публикацией = десктоп-exe в один клик; без среды автоматически headless.

if (xsWebviewAvailable()) openDesktop();

Ваша библиотека

одна запись в extensions.json

Укажите файлы исходников, заголовок VFS и import-таблицу — реестр проверит escape-пути, дубликаты макросов и конфликты имён, с двойной верификацией юнит-тестами и рантайм-зондами.

{ "name": "mylib", "macro": "XS_USE_MYLIB" }

Верните сервер в один файл

Рантайм xrt + хост XServer + ваши исходники на C — начните прямо сейчас.

Дружеские ссылки