Coroutines As Connection Handlers

lua-users home
wiki

This shows the basic scaffolding one might use for handling multiple sockets (e.g. TCP or otherwise) via coroutines. (The actual socket code is omitted for brevity.) To avoid writing this scaffolding you might alternately use the Copas library as shown in CopasExample.

function read()
    return coroutine.yield()
end

function write_socket(socket, data)
    print("i'm writing to socket " .. socket .. ": " .. data)
end

function connection_handler(socket)
    write_socket(socket, "hi!")
    local input = read()
    write_socket(socket, "the input was: " .. input)
    local input = read()
    write_socket(socket, "even more input was: " .. input)
    if socket == 2 then
       error("example error in socket 2")
    end
end

function create_connection_handler(socket)
    local handler = coroutine.create(connection_handler)
    coroutine.resume(handler, socket)
    return handler
end

connections = {}

function accept_connection(socket)
    print("accepted socket " .. socket)
    connections[socket] = create_connection_handler(socket)
end

function close_connection(socket)
    connections[socket] = nil
    -- close your socket here
    print("socket " .. socket .. " closed")
end

function handle_socket_data(socket, data)
    local ok, msg = coroutine.resume(connections[socket], data)
    if not ok then
        print("the handler for socket " .. socket .. " failed: " .. msg)
        close_connection(socket)
    elseif ok and coroutine.status(connections[socket]) == "dead" then
        print("the handler for socket " .. socket .. " finished")
        close_connection(socket)
    end
end

-- In a real application, these will be created after you 
-- accept()ed a new connection
accept_connection(1)
accept_connection(2)
accept_connection(3)

-- In a real application, you'll use some dispatcher to read 
-- data from sockets and then call handle_socket_data.

-- Data on socket 1
handle_socket_data(1, "here is some data")

-- Data on socket 2
handle_socket_data(2, "here is data for socket 2")

-- More Data on socket 1
handle_socket_data(1, "wow. more data")

-- hm. socket 3 was closed by the user
close_connection(3)

-- Data on socket 2
handle_socket_data(2, "ok. enough :)")

See Also


RecentChanges · preferences
edit · history
Last edited January 10, 2007 4:08 am GMT (diff)