serverino 0.7.17
Small and ready-to-go http server. Support for websockets included.
To use this package, run the following command in your project's root directory:
Manual usage
Put the following dependency into your project's dependences section:
serverino <img align="left" alt="Logo" width="100" src="https://github.com/trikko/serverino/assets/647157/a6f462fa-8b76-43c3-9855-0671e704aa6c" height="96">
- 🚀 Quick build & start: build & run your server in seconds.
- 🙌 Zero dependencies: serverino doesn't rely on any external library.
- 💪 High performance: capable of managing tens of thousands of connections per second.
- 🌐 Cross-platform: every release is tested on Linux, Windows, and MacOS.
- 🔄 Hot-reload: restart workers without downtime or dropped connections. [(how?)](#restarting-workers-without-downtime)
Quickstart
Install a dlang compiler, then:
dub init your_app_name -t serverino
cd your_app_name
dub run
A simple webserver in just three lines
import serverino;
mixin ServerinoMain;
void simple(Request request, Output output) { output ~= request.dump(); }
Documentation you need
- Serverino docs - Serverino reference, generated from code
- Examples - Some ready-to-try examples
- Tips - Some snippets you want to read
Defining more than one endpoint
[!IMPORTANT] All the functions marked with
`@endpoint
will be called one by one, in order of
@priority
` (higher to lower), until one of them modifies the output.
module app;
import std;
import serverino;
mixin ServerinoMain;
// This endpoint handles the root of the server. Try: http://localhost:8080/
@endpoint @route!"/"
void homepage(Request request, Output output)
{
output ~= `<html><body>`;
output ~= `<a href="/private/profile">Private page</a><br>`;
output ~= `<a href="/private/asdasd">Private (404) page</a>`;
output ~= `</body></html>`;
}
// This endpoint shows a private page: it's protected by the auth endpoint below.
@endpoint @route!"/private/profile"
void user(Request request, Output output)
{
output ~= "Hello user!";
}
// This endpoint shows a private page: it's protected by the auth endpoint below.
@endpoint
void blah(Request request, Output output)
{
// Same as marking this endpoint with @route!"/private/dump"
if (request.path != "/private/dump")
return;
output ~= request.dump();
}
// This endpoint simply checks if the user and password are correct for all the private pages.
// Since it has a higher priority than the previous endpoints, it will be called first.
@priority(10)
@endpoint @route!(r => r.path.startsWith("/private/"))
void auth(Request request, Output output)
{
if (request.user != "user" || request.password != "password")
{
// If the user and password are not correct, we return a 401 status code and a www-authenticate header.
output.status = 401;
output.addHeader("www-authenticate",`Basic realm="my serverino"`);
}
// If the user and password are correct, we call the next matching endpoint.
// (the next matching endpoint will be called only if the current endpoint doesn't write anything)
}
// This endpoint has the highest priority between the endpoints and it logs all the requests.
@priority(12) @endpoint
void requestLog(Request request)
{
// There's no http output, so the next endpoint will be called.
info("Request: ", request.path);
}
[!NOTE] Using
Fallthrough.Yes
as a return value for a endpoint allows you to avoid stopping the flow even if the output is touched.
Websockets
// Accept a new connection only if the request path is "/echo"
// Every websocket will start a new indipendent process
@onWebSocketUpgrade bool onUpgrade(Request req) {
return req.path == "/echo";
}
// Handle the WebSocket connection
// Just like a normal endpoint, but with a WebSocket parameter
@endpoint void echo(Request r, WebSocket ws) {
// Keep the websocket running
while (true) {
// Try to receive a message from the client
if (WebSocketMessage msg = ws.receiveMessage())
{
// If we received a message, send it back to the client
ws.send("I received your message: `" ~ msg.asString ~ "`");
}
}
// When the function returns, the WebSocket connection is closed
}
Restarting workers without downtime
[!CAUTION] Hot-reloading only affects the worker processes, not the main daemon process. If you modify code in the main daemon process, those changes will not be applied until you fully restart the server. Only changes to endpoint handlers and worker-specific code will be picked up by the hot-reload mechanism.
Serverino workers can be restarted on demand without causing downtime.
- On POSIX systems: send
SIGUSR1
signal to the main process withkill -10 <daemon_pid>
orkill -SIGUSR1 <daemon_pid>
- On Windows: delete the canary file in the temp folder named
serverino-pid-<sha256 of pid>.canary
This allows you to recompile your workers and perform hot-reloading of your application code without any service interruption or dropped connections.
Shielding the whole thing
[!CAUTION] I recommend securing serverino behind a full web server. Below, I provide two examples of how to run serverino with nginx and apache.
Using nginx
It's pretty easy. Just add these lines inside your nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
location /your_path/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8080;
}
...
...
}
If you want to enable keepalive (between nginx and serverino) you must use an upstream:
upstream your_upstream_name {
server localhost:8080;
keepalive 64;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
location /your_path/ {
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://your_upstream_name;
}
...
...
}
Using apache2
Enable proxy module for apache2:
sudo a2enmod proxy
sudo a2enmod proxy_http
Add a proxy in your virtualhost configuration:
<VirtualHost *:80>
ProxyPass "/" "http://localhost:8080/"
...
</VirtualHost>
- 0.7.17 released 7 days ago
- trikko/serverino
- MIT
- Copyright © 2023-2024, Andrea Fontana
- Authors:
- Sub packages:
- serverino:init-exec
- Dependencies:
- serverino:init-exec
- Versions:
-
0.7.17 2025-May-24 0.7.16 2025-Jan-16 0.7.15 2025-Jan-10 0.7.14 2024-Dec-26 0.7.13 2024-Dec-18 - Download Stats:
-
-
0 downloads today
-
13 downloads this week
-
34 downloads this month
-
1614 downloads total
-
- Score:
- 2.9
- Short URL:
- serverino.dub.pm