Tiny Http – Server and Client for Defold

Human Trials

Tiny Http - Defold Native Extension is a simple http server and client.

Server works on iOS, Android, MacOS, Win 10 and Linux(Debian 10.x). HTML5 build is not supported. Since I don’t need it, SSL not supported. But it is possible to add this feature, feel free to PR if you want to.

All requests and responses are JSON. You may consider of using CJSON for encoding and decoding.

All server responses for GET requests are static echo. POST responses are limited but customizable by using dhttp.server_post_content.

Server runs on separate thread, it is not a blocker. Client has a thread pool. But timeouts may block the UI for 5 sec. Server endpoints are definable. You can add your GET/POST endpoints by using regex.

There is a simple Event ID passing from client to server. Event IDs are passed as header. Main purpose of Event ID is to grouping and parsing the triggers on the server-side easily.

Client is here to simplify things when using Defold. But of course you can use build-in http requests. If you want to use build-in http requests and Event-IDs, you can simply pass it like this:


local headers = {
    ["Event-ID"] = "1"
}

http.request("http://127.0.0.1:8800/monster/1", "GET", http_result, headers)


 

Or with Curl:


curl --header \\"Event-ID: 1\\" http://localhost:8800/monster/1

 

Installation

You can use Tiny Http in your own project by adding this project as a Defold library dependency. Open your game.project file and in the dependencies field under project add:

https://github.com/selimanac/defold-tiny-http/archive/master.zip

Examples

Detailed server and client examples can be found in examples folder.

Server

-- Server settings
local host = "localhost"
local port = 8800

-- Server callbacks
local function server_callbacks(self, message)
	-- Decode response
    local jresult = json.decode(message.result)
    local event_id = message.event_id

    if jresult.server_status == dhttp.SERVER_START then
        -- Server started
    elseif jresult.server_status == dhttp.SERVER_STOP then
        -- Server stopped
    else
    	if event_id == 123 then
        	pprint(jresult)
        	-- Do something fancy
       end
    end
end

function init(self)
    -- Start the server
    dhttp.server_start(host, port, server_callbacks)
end

Client

-- Client settings
local host = "localhost"
local port = 8800

-- Client callbacks
local function client_callbacks(self, message)
    -- Decode response
    local jresult = json.decode(message.result)

    -- Check error
    if jresult.error then
        print("Error: ", jresult.error)
        return
    end

    pprint(jresult)
end

function init(self)
    -- Init the client
    dhttp.client_start(host, port, client_callbacks)

    -- Get endpoint
    dhttp.client_get("/hi", 123)
end

Server API

dhttp.server_start(host, port, callback, [log], [error], [endpoints])

Init and start the server.

ParamDesc
host(string) Host address or IP
port(int) Port number
callback(function) Callback function
[log](boolean) Turn logging on/off. Default is false
[error](boolean) Turn error responses on/off. Default is true
[endpoints](table) Optional endpoints

dhttp.server_stop()

Gracefully shutdown the server.

dhttp.is_server_running()

Check if server is running. Returns boolean.

dhttp.server_post_content(content)

Sets the POST response for all POST endpoints. You can set this anytime.

ParamDesc
content(string) JSON formated string

Endpoints

There are several built-in endpoints.

EndpointDesc
“/hi”Says hi!
“/num/(\d+)”(GET) Gets only [0-9] as integer
“/str/(\w+)”(GET) Gets only [a-zA-Z0-9] as string
“/post”(POST) Generic post endpoint with params
“/stop”(GET) Stop the server

You can define custom endpoints.
Endpoints support regex. But “?” character is reserved and may cause a crash.

local endpoints = {
    {
        endpoint_type = dhttp.METHOD_GET,
        endpoint = "/monster/(\\d+)"
    },
    {
        endpoint_type = dhttp.METHOD_POST,
        endpoint = "/move"
    }
}

dhttp.server_start("localhost", 8888, server_callbacks, false, true, endpoints)

Client API

dhttp.client_start(host, port, client_callbacks)

Init the client.

ParamDesc
host(string) Host address or IP
port(int) Port number
callback(function) Callback function

dhttp.client_hi()

Defold says hi!

dhttp.client_get(endpoint, [event_id])

ParamDesc
endpoint(string) Endpoint address
[event_id](int) Event ID for tracking the action

Event IDs are for tracking the requests on server and client. They send as a header. You can easily group and parse your triggers by using event ids.

dhttp.client_post(endpoint, params, [event_id])

ParamDesc
endpoint(string) Endpoint address
params(string) JSON formated string
[event_id](int) Event ID for tracking the action

Event IDs are for tracking the requests on server and client. They send as a header. You can easily group and parse your triggers by using event ids.

local temp_table = {
        x = 10,
        y = 20
    }

    jresult = cjson.encode(temp_table)

    local params = {
        position = jresult
    }

    dhttp.client_post("/post", params, 1)

Constants

dhttp.METHOD_GET
dhttp.METHOD_POST
dhttp.SERVER_START
dhttp.SERVER_STOP

Dependencies

Build by using cpp-httplib
Characters by @bevouliin