Skip to content

Instantly share code, notes, and snippets.

@imolein
Last active September 14, 2018 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imolein/74d1154e541ef7866177a587b43688f1 to your computer and use it in GitHub Desktop.
Save imolein/74d1154e541ef7866177a587b43688f1 to your computer and use it in GitHub Desktop.
An ugly question server, written to learn how coroutines work
local socket = require("socket")
local inspect = require('inspect')
local host = "127.0.0.1"
local port = 9090
if arg then
host = arg[1] or host
port = arg[2] or port
end
udp = assert(socket.udp())
assert(udp:setsockname(host, port))
assert(udp:settimeout(2))
ip, port = udp:getsockname()
assert(ip, port)
print("Server started on " .. ip .. ":" .. port .. "...")
local function questioner(dgram, ip, port)
if dgram:lower() ~= 'hallo\n' then return end
local questions = {
'Wie ist dein Name?\n',
'Wie alt bist du?\n',
'Wo wohnst du?\n'
}
local answers = {}
for _, q in ipairs(questions) do
if not answers[q] then
print('Asking: ' .. q .. 'to' .. ip .. ':' .. port)
udp:sendto(q, ip, port)
answers[q] = coroutine.yield():sub(1, -2)
end
end
local final = string.format('Du heißt %s, bist %d Jahre alt und kommst aus %s!\n', answers['Wie ist dein Name?\n'], answers['Wie alt bist du?\n'], answers['Wo wohnst du?\n'])
udp:sendto(final, ip, port)
end
local CLIENTS = {}
while 1 do
local dgram, ip, port = udp:receivefrom()
if dgram and dgram ~= '\n' then
if CLIENTS[port] then
coroutine.resume(CLIENTS[port], dgram)
else
CLIENTS[port] = coroutine.create(questioner)
local s, e = coroutine.resume(CLIENTS[port], dgram, ip, port)
if not s then print(e) end
end
if coroutine.status(CLIENTS[port]) == 'dead' then
CLIENTS[port] = nil
end
else
print(ip)
end
print(inspect(CLIENTS))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment