Eluna
Eluna copied to clipboard
feat: add HttpRequest method
This PR adds the possibility to perform HTTP/HTTPS requests in a non-blocking way (they are queued up and executed one by one in a separate thread). The requests can be executed via the HttpRequest
global function.
Example usage, from the function's docs:
-- GET example (prints a random word)
HttpRequest("GET", "https://random-word-api.herokuapp.com/word", function(status, body, headers)
print("Random word: " .. string.sub(body, 3, body:len() - 2))
end)
-- POST example with JSON request body
HttpRequest("POST", "https://jsonplaceholder.typicode.com/posts", '{"userId": 1,"title": "Foo","body": "Bar!"}', "application/json", function(status, body, headers)
print(body)
end)
-- Example with request headers
HttpRequest("GET", "https://postman-echo.com/headers", { Accept = "application/json", ["User-Agent"] = "Eluna Lua Engine" }, function(status, body, headers)
print(body)
end)
The following 3rd party libraries are used by this PR:
- yhirose/cpp-httplib (MIT license)
- rigtorp/SPSCQueue (MIT license)
Another example usage: (this example requires json.lua)
local json = require("json")
RegisterPlayerEvent(42, function(event, player, command)
if command == "joke" then
local guid = player:GetGUID()
HttpRequest("GET", "https://api.chucknorris.io/jokes/random", function(status, body, headers)
local player = GetPlayerByGUID(guid)
res = json.decode(body)
player:SendBroadcastMessage(res.value)
end)
return false
end
end)
Result:
I didn't originally merge this because I am not quite sure if its something that should be included in Eluna. I think the functionality should be a part of the core, which is then exposed by Eluna. Or it should be a DLL/SO that is then loaded by eluna and operated from it, but that would be less convenient.
Thoughts?
I'll try to move the http functionality to the core and expose it in Eluna instead. I'll comment here when I'm done.
Maybe this could be added as a compiled module and an extension? Compile something like https://github.com/ledgetech/lua-resty-http into a lua module and then load that in an extension? You don't need multithreading for something as simple as a HTTP request, you can just use a coroutine with a non-blocking http request as shown here: https://www.lua.org/pil/9.4.html . Just wrap that up in an extension and then do a Global:RegisterServerEvent WORLD_EVENT_ON_UPDATE and run the coroutine there.
(Though down the road adding support for native threads with something like https://github.com/effil/effil is not a terrible idea altogether)
@r-o-b-o-t-o check https://github.com/ElunaLuaEngine/Eluna/pull/412
I wrapped this up as a module https://github.com/anzz1/eluna-module-httpmanager
I wrapped this up as a module https://github.com/anzz1/eluna-module-httpmanager
I think this would be a good way to deal with this, having a unified API is definitely a good way to deal with this