Skip to content

Instantly share code, notes, and snippets.

@yangfch3
Created September 27, 2021 08:04
Show Gist options
  • Save yangfch3/3c717f7d472fba46cf4c395354c497cd to your computer and use it in GitHub Desktop.
Save yangfch3/3c717f7d472fba46cf4c395354c497cd to your computer and use it in GitHub Desktop.
Lua simple http server | Lua 简易 HTTP 服务器
--[[
A simple HTTP server
If a request is not a HEAD method, then reply with "Hello world!"
Usage: lua examples/server_hello.lua [<port>]
]]
local MyLog = require "AIServer/MyLog"
local http_server = require "http.server"
local http_headers = require "http.headers"
local json = require "3rds/json"
local ReqHandle = require "AIServer/ReqHandle"
local port = arg[1] or 8868 -- 0 means pick one at random
local isBg = arg[2] or false
if isBg then
MyLog.ensureStdLogFile()
end
--[[
method: Get/POST
body: {
game_data = {
seatIndex = 1,
playerNum = 4,
-- 以下按照 seatIndex 从 1 - n
handCards = [[1,2, ...], ...],
stockCards = [[1,2, ...], ...],
discards = [
[[1,2, ...], ...],
...
],
}
}
--]]
local function reply(myServer, stream)
local req_headers = assert(stream:get_headers())
local req_method = req_headers:get ":method"
local req_body = stream:get_body_as_string()
-- Log request to stdout
assert(io.stdout:write(
string.format('[%s] "%s %s HTTP/%g" "%s" "%s"\n',
os.date("%d/%b/%Y:%H:%M:%S %z"),
req_method or "",
req_headers:get(":path") or "",
stream.connection.version,
req_headers:get("referer") or "-",
req_headers:get("user-agent") or "-"
)
)
)
-- Build response headers
local res_headers = http_headers.new()
res_headers:append(":status", "200")
res_headers:append("content-type", "application/json; charset=utf-8")
-- Send headers to client; end the stream immediately if this was a HEAD request
assert(stream:write_headers(res_headers, req_method == "HEAD"))
-- Build Body
local res_body = {
err_code = 0,
msg = "ok",
data = {}
}
if req_body and string.find(req_body, "game_data") then
MyLog.stdWrite(req_body)
local handle = ReqHandle.New(json.decode(req_body).game_data)
local decisionList = handle:DoHandle()
res_body.data.decisionList = decisionList
else
MyLog.stdWrite("req: Not conform to the specifications req data.\n")
end
if req_method ~= "HEAD" then
-- Send body, ending the stream
local res_body = json.encode(res_body)
MyLog.stdWrite("res: " .. res_body .. "\n")
assert(stream:write_body_from_string(res_body))
end
io.stdout:flush()
end
local myServer = assert(http_server.listen {
host = "127.0.0.1";
port = port;
onstream = reply;
onerror = function(myServer, context, op, err, errno)
local msg = op .. " on " .. tostring(context) .. " failed"
if err then
msg = msg .. ": " .. tostring(err) .. "\n"
end
MyLog.stdErrWrite(msg)
end;
})
-- Manually call :listen() so that we are bound before calling :localname()
assert(myServer:listen())
do
local bound_port = select(3, myServer:localname())
MyLog.stdWrite(string.format("Now listening on port %d\n", bound_port))
end
-- Start the main server loop
assert(myServer:loop())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment