Multi threading with Lua



I want to create asynchronous HTTP requests and still be able to use Lua to generate scenes.
However, all of my scenes call my APIs on server to receive data, which is then shown on screen.

I want to use pthreads & libcurl easy interface to deal with http requests and then perform a callback to lua, unfortunately, the lua_State used by lua to call a cfunction is closed by the time the callback is made, so I have to open a new lua_State.
If I open new lua state I cannot access the object, to which I want to send the response.
Maybe I’m wrong, but it is possible to have something like this:

function decorate(obj) 

  [create everything on the scene]

  function obj:callback(xmlString)
    [update the scene using data received from server]

  function obj:httpRequest()
    local function callback(xmlString) self:callback(xmlString) end
    sendHttpRequestUsingCFunction(url, callback)



So I will create a scene and call a cfunction passing a pointer to a lua function. CFunction will create a new thread and return. In new thread I will call my server, receive xml and call the callback function passing the xml string.

How can I achieve this?


a little mind of binding luasocket to cocos2d-x

download llthreads from
integrating llthreads to your project, reference

create network.lua

module("network", package.seeall)
local _llthreads = require("llthreads")
local _url       = require("socket.url")
local _http      = require("socket.http")
local _ltn12     = require("ltn12")
local _mime      = require("mime")

--[[ generate URL-encoded query string

    local query = network.http_build_query({
        title = "Title",
        message = "Hello"
function http_build_query(params)
    local query = ""
    for k, v in pairs(params) do
        query = query..string.format("%s=%s&", k, _url.escape(v))
    return string.sub(query, 1, string.len(query) - 1)

local request_thread_code = [[
    local _http  = require("socket.http")
    local _ltn12 = require("ltn12")

    local args = ...
    local url = args.url
    local method = args.method
    local response = {}

    _http.TIMEOUT = args.timeout or 10

    local requestParams = {
        url    = url,
        method = method,
        sink   = _ltn12.sink.table(response)
    local params = args.params
    if type(params) == "table" then
        if params.body then
            requestParams.source = _ltn12.source.string(tostring(params.body))
        if params.headers then
            requestParams.headers = params.headers

    local result, code, headers = _http.request(requestParams)
    return result, code, headers, table.concat(response)

-- makes an asynchronous HTTP or HTTPS request to a URL
function request(url, method, listener, params)
    local thread
    local function onComplete(result, code, headers, response)
        if result then
            -- succeed
            listener(true, code, headers, response)
            -- failed
            listener(false, code) -- code is error message
        thread = nil -- reference to thread object, avoid gc call join()

    if type(params) == "table" and type(params.body) == "table" then
        params.body = http_build_query(params.body)

    thread =, onComplete, {
        url = url,
        method = method,
        timeout = 3,
        params = params

How to use:


local function onRequestCompleted(ok, code, headers, response)
    if not ok then
        -- request failed, code is error code

    -- response is remote data, HTML, JSON string, etc..

local query = ""
local params = {
    body = {  -- POST data
        key         = "111",
        key2        = "222"
network.request(query, "POST", onRequestCompleted, params)

good luck :slight_smile:

Cannot load modules in the thread code which started by llthreads


I’m shocked [again] by completeness of your answer!
Thank you very much!

I am only wondering if you have ever tried to run this on Android?
I will have to update some of the make files probably.


I use these code in my iOS game, Android not tried.


very good example, marked!


After integrating the llthreads into cocos2d-x 3.16. I can start a new thread via…). But in the thread, I could not require some modules. I saw “module ‘xxxx’ not found” message.
These modules can be loaded successfully in the cocos2d-x main thread.