diff --git a/doc/ru/scripting/builtins/libnetwork.md b/doc/ru/scripting/builtins/libnetwork.md index c9cc890c..16f9dd5c 100644 --- a/doc/ru/scripting/builtins/libnetwork.md +++ b/doc/ru/scripting/builtins/libnetwork.md @@ -72,6 +72,12 @@ socket:is_connected() --> bool -- Возвращает адрес и порт соединения. socket:get_address() --> str, int + +-- Возвращает состояние NoDelay +socket:get_nodelay() --> bool + +-- Устанавливает состояние NoDelay +socket:set_nodelay(state: bool) ``` ```lua diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index e63d5a5a..0d422b04 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -44,6 +44,8 @@ local Socket = {__index={ is_alive=function(self) return network.__is_alive(self.id) end, is_connected=function(self) return network.__is_connected(self.id) end, get_address=function(self) return network.__get_address(self.id) end, + set_nodelay=function(self, nodelay) return network.__set_nodelay(self.id, nodelay or false) end, + get_nodelay=function(self) return network.__get_nodelay(self.id) end, }} local WriteableSocket = {__index={ diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index 94390c93..af7dedef 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -382,6 +382,28 @@ static int l_get_total_download(lua::State* L, network::Network& network) { return lua::pushinteger(L, network.getTotalDownload()); } +static int l_set_nodelay(lua::State* L, network::Network& network) { + u64id_t id = lua::tointeger(L, 1); + bool noDelay = lua::toboolean(L, 2); + if (auto connection = network.getConnection(id)) { + if (connection->getTransportType() == network::TransportType::TCP) { + dynamic_cast(connection)->setNoDelay(noDelay); + } + } + return 0; +} + +static int l_get_nodelay(lua::State* L, network::Network& network) { + u64id_t id = lua::tointeger(L, 1); + if (auto connection = network.getConnection(id)) { + if (connection->getTransportType() == network::TransportType::TCP) { + bool noDelay = dynamic_cast(connection)->getNoDelay(); + return lua::pushboolean(L, noDelay); + } + } + return lua::pushboolean(L, false); +} + static int l_pull_events(lua::State* L, network::Network& network) { lua::createtable(L, events_queue.size(), 0); @@ -458,5 +480,7 @@ const luaL_Reg networklib[] = { {"__get_address", wrap}, {"__is_serveropen", wrap}, {"__get_serverport", wrap}, + {"__set_nodelay", wrap}, + {"__get_nodelay", wrap}, {NULL, NULL} }; diff --git a/src/network/Network.cpp b/src/network/Network.cpp index 234197e4..337193ed 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -329,6 +329,22 @@ public: } } + void setNoDelay(bool noDelay) override { + int opt = noDelay ? 1 : 0; + if (setsockopt(descriptor, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt)) < 0) { + throw handle_socket_error("setsockopt(TCP_NODELAY) failed"); + } + } + + bool getNoDelay() const override { + int opt = 0; + socklen_t len = sizeof(opt); + if (getsockopt(descriptor, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, &len) < 0) { + throw handle_socket_error("getsockopt(TCP_NODELAY) failed"); + } + return opt != 0; + } + void startListen() { while (state == ConnectionState::CONNECTED) { int size = recvsocket(descriptor, buffer.data(), buffer.size()); diff --git a/src/network/Network.hpp b/src/network/Network.hpp index ddde70b5..5074bcab 100644 --- a/src/network/Network.hpp +++ b/src/network/Network.hpp @@ -76,6 +76,8 @@ namespace network { virtual void connect(runnable callback) = 0; virtual int recv(char* buffer, size_t length) = 0; virtual int available() = 0; + virtual void setNoDelay(bool noDelay) = 0; + [[nodiscard]] virtual bool getNoDelay() const = 0; [[nodiscard]] TransportType getTransportType() const noexcept override { return TransportType::TCP;