Hello!
You’re right to notice a conceptual gap: OpenResty is built on NGINX, which is fundamentally an HTTP server, whereas traditional socket servers (like those you’d build in Luvit) often deal with raw TCP/UDP connections. That makes the programming model a little different. Here’s a breakdown:
- OpenResty is HTTP-centric
OpenResty extends NGINX with Lua scripting via lua-nginx-module, so most of your Lua code runs in the context of HTTP requests. This makes it great for web APIs, web sockets, and handling HTTP traffic at very high performance—but it’s not a general-purpose TCP server out of the box.
- WebSockets for persistent connections
If you want a persistent, bidirectional connection (like in a multiplayer game), OpenResty supports WebSockets through third-party libraries or NGINX modules. You can think of this as “socket-like” behavior over HTTP:
The client connects using the WebSocket protocol.
NGINX handles the upgrade request from HTTP → WebSocket.
Your Lua code manages message handling in OpenResty.
Example workflow:
-- pseudo-code
local server = require "resty.websocket.server"
local wb, err = server:new{ timeout = 5000, max_payload_len = 65535 }
if not wb then
ngx.log(ngx.ERR, "failed to create websocket: ", err)
return
end
while true do
local data, typ, err = wb:recv_frame()
if not data then
break
end
-- handle your game logic
wb:send_text("Echo: " .. data)
end
This lets you build real-time features, but all traffic is tunneled over WebSocket, not raw TCP.
- Limitations compared to Luvit
Raw TCP/UDP: OpenResty doesn’t natively let you open arbitrary TCP/UDP ports like Luvit does. You’d need to use NGINX stream module for TCP/UDP, but that’s less flexible for scripting in Lua.
Event loop: OpenResty’s Lua code runs in NGINX’s worker model; it’s non-blocking but tied to HTTP request lifecycles. Luvit gives you a pure Lua event loop similar to Node.js, which can feel more natural for game servers.
- When to choose OpenResty
You want HTTP APIs and occasional WebSocket connections.
You want high-performance routing, caching, or load balancing.
You’re comfortable structuring your game server around WebSockets rather than raw sockets.
If your game is heavily real-time and requires direct TCP/UDP, Luvit or a dedicated Lua socket server might still be simpler.
💡 TL;DR: OpenResty can do “socket-like” servers via WebSockets, but it is not a drop-in replacement for a raw TCP/UDP server. Luvit gives more direct control for traditional game servers, while OpenResty shines for web-driven, high-performance architectures.