Skip to content

Commit

Permalink
Add udp example and more api
Browse files Browse the repository at this point in the history
  • Loading branch information
Dregu committed Sep 11, 2024
1 parent 0a6f418 commit 63d1a11
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
82 changes: 82 additions & 0 deletions examples/udp.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
meta = {
name = "UDP echo example",
description = "Opens UDP server on a random port and echoes sent messages, closes the server on 'gg'",
author = "Dregu",
unsafe = true
}

options = {
host = "127.0.0.1",
port = 0
}

function init()
deinit()

server = {
-- Save messages to queue instead of printing directly, cause that doesn't work from the server thread
queue = {},

-- Open server on an ephemeral random port, push messages to queue and echo back to sender
socket = udp_listen(options.host, options.port, function(msg)
msg = msg:gsub("%s*$", "")
table.insert(server.queue, msg)
if msg == "gg" then
return "bye!\n"
else
return "echo: " .. msg .. "\n"
end
end)
}

-- If port was opened successfully, start checking the message queue
if server.socket:open() then
print(F "Listening on {server.socket.port}, please send some UDP datagrams or 'gg' to close")
server.inter = set_global_interval(function()
for _, msg in pairs(server.queue) do
print(F "Received: {msg}")
if msg == "gg" then
server.socket:close()
clear_callback()
print("Server is now closed, have a nice day")
end
end
server.queue = {}
end, 1)
else
print(F "Failed to open server: {server.socket:error()}")
end
end

function deinit()
if server then
server.socket:close()
if server.inter then clear_callback(server.inter) end
server = nil
end
end

set_callback(init, ON.LOAD)
set_callback(init, ON.SCRIPT_ENABLE)
set_callback(deinit, ON.SCRIPT_DISABLE)

register_option_callback("x", nil, function(ctx)
options.host = ctx:win_input_text("Host", options.host)
options.port = ctx:win_input_int("Port", options.port)
if options.port < 0 then options.port = 0 end
if options.port > 65535 then options.port = 65535 end
if ctx:win_button("Start server") then init() end
ctx:win_inline()
if ctx:win_button("Stop server") then deinit() end
if server then
ctx:win_text(server.socket:error())
end
if server and server.socket:open() then
ctx:win_text(F "Listening on {server.socket.host}:{server.socket.port}\nTry sending something with udp_send:")
if ctx:win_button("Send 'Hello World!'") then udp_send(server.socket.host, server.socket.port, "Hello World!") end
ctx:win_inline()
if ctx:win_button("Send 'gg'") then udp_send(server.socket.host, server.socket.port, "gg") end
else
ctx:win_text("Stopped")
end
end)
6 changes: 3 additions & 3 deletions src/game_api/script/usertypes/socket_lua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ namespace NSocket
void register_usertypes(sol::state& lua)
{
lua.new_usertype<UdpServer>(
"UdpServer", sol::no_constructor, "close", &UdpServer::close, "open", &UdpServer::open, "error", &UdpServer::error);
"UdpServer", sol::no_constructor, "close", &UdpServer::close, "open", &UdpServer::open, "error", &UdpServer::error, "host", sol::readonly(&UdpServer::host), "port", sol::readonly(&UdpServer::port));

/// Start an UDP server on specified address and run callback when data arrives. Return a string from the callback to reply. Requires unsafe mode.
/// The server will be closed lazily by garbage collection once the handle is released, or immediately by calling close().
/// Start an UDP server on specified address and run callback when data arrives. Set port to 0 to use a random ephemeral port. Return a string from the callback to reply.
/// The server will be closed lazily by garbage collection once the handle is released, or immediately by calling close(). Requires unsafe mode.
lua["udp_listen"] = [](std::string host, in_port_t port, sol::function cb)
{
return std::unique_ptr<UdpServer>{new UdpServer(std::move(host), std::move(port), make_safe_cb<UdpServer::SocketCb>(std::move(cb)))};
Expand Down
2 changes: 2 additions & 0 deletions src/game_api/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ UdpServer::UdpServer(std::string host_, in_port_t port_, std::function<SocketCb>
{
if (sock.bind(sockpp::inet_address(host, port)))
{
const auto addr = (sockpp::inet_address)sock.address();
port = addr.port();
is_opened = true;
sock.set_non_blocking();
kill_thr.test_and_set();
Expand Down
2 changes: 1 addition & 1 deletion src/game_api/socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class UdpServer
/// Closes the server.
void close();

/// Returns true if the port was opened successfully and hasn't been closed yet.
/// Returns true if the port was opened successfully and the server hasn't been closed yet.
bool open();

/// Returns a string explaining the last error, at least if open() returned false.
Expand Down

0 comments on commit 63d1a11

Please sign in to comment.