diff --git a/doc/ru/scripting/builtins/libnetwork.md b/doc/ru/scripting/builtins/libnetwork.md index c880240c..bef8967c 100644 --- a/doc/ru/scripting/builtins/libnetwork.md +++ b/doc/ru/scripting/builtins/libnetwork.md @@ -93,6 +93,12 @@ socket:is_connected() --> bool -- Возвращает адрес и порт соединения. socket:get_address() --> str, int + +-- Возвращает состояние NoDelay +socket:is_nodelay() --> bool + +-- Устанавливает состояние NoDelay +socket:set_nodelay(state: bool) ``` ```lua diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index 49d11268..27a73c97 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, + is_nodelay=function(self) return network.__is_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 6e548cf9..a78f17db 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -402,6 +402,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_is_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)->isNoDelay(); + return lua::pushboolean(L, noDelay); + } + } + return lua::pushboolean(L, false); +} + static int l_pull_events(lua::State* L, network::Network& network) { std::vector local_queue; { @@ -517,5 +539,7 @@ const luaL_Reg networklib[] = { {"__get_address", wrap}, {"__is_serveropen", wrap}, {"__get_serverport", wrap}, + {"__set_nodelay", wrap}, + {"__is_nodelay", wrap}, {NULL, NULL} }; diff --git a/src/network/Network.cpp b/src/network/Network.cpp index 2a1aacc8..f4e9db9b 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -355,6 +355,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 isNoDelay() 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 3e9feeda..3fec46e0 100644 --- a/src/network/Network.hpp +++ b/src/network/Network.hpp @@ -77,6 +77,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 isNoDelay() const = 0; [[nodiscard]] TransportType getTransportType() const noexcept override { return TransportType::TCP;