diff --git a/CMakeLists.txt b/CMakeLists.txt index 413147f..19c6e3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.24) -project(native_streaming VERSION 1.0.16 LANGUAGES CXX) +project(native_streaming VERSION 1.0.17 LANGUAGES CXX) if (NOT CMAKE_MESSAGE_CONTEXT) set(CMAKE_MESSAGE_CONTEXT ${PROJECT_NAME}) diff --git a/include/native_streaming/client.hpp b/include/native_streaming/client.hpp index f3a5291..7e339fb 100644 --- a/include/native_streaming/client.hpp +++ b/include/native_streaming/client.hpp @@ -68,9 +68,12 @@ class Client : public std::enable_shared_from_this /// @brief creates a connection Session using provided web-socket stream object /// @param wsStream web-socket stream object which provides as a R/W interface for connection - /// @param endpointAddress string with the address in the format IP:port of the connection endpoint associated with the session + /// @param endpointAddress the IP address of the connection endpoint associated with the session + /// @brief endpointPortNumber the port number of the connection endpoint associated with the session /// @return pointer to created Session object - std::shared_ptr createSession(std::shared_ptr wsStream, const std::string& endpointAddress); + std::shared_ptr createSession(std::shared_ptr wsStream, + const std::string& endpointAddress, + const boost::asio::ip::port_type& endpointPortNumber); /// async operations handler std::shared_ptr ioContextPtr; diff --git a/include/native_streaming/server.hpp b/include/native_streaming/server.hpp index 58679be..d845996 100644 --- a/include/native_streaming/server.hpp +++ b/include/native_streaming/server.hpp @@ -83,11 +83,13 @@ class Server : public std::enable_shared_from_this /// @brief creates a connection Session using provided web-socket stream object /// @param wsStream web-socket stream object which provides as a R/W interface for connection /// @param user context, usualy a pointer to the authenticated user object - /// @param endpointAddress string with the address in the format IP:port of the connection endpoint associated with the session + /// @param endpointAddress the IP address of the connection endpoint associated with the session + /// @brief endpointPortNumber the port number of the connection endpoint associated with the session /// @return pointer to created Session object std::shared_ptr createSession(std::shared_ptr wsStream, const std::shared_ptr& userContext, - const std::string& endpointAddress); + const std::string& endpointAddress, + const boost::asio::ip::port_type& endpointPortNumber); /// async operations handler std::shared_ptr ioContextPtr; diff --git a/include/native_streaming/session.hpp b/include/native_streaming/session.hpp index c880108..9d32829 100644 --- a/include/native_streaming/session.hpp +++ b/include/native_streaming/session.hpp @@ -37,7 +37,8 @@ class Session : public std::enable_shared_from_this std::shared_ptr userContext, boost::beast::role_type role, LogCallback logCallback, - const std::string& endpointAddress); + const std::string& endpointAddress, + const boost::asio::ip::port_type& endpointPortNumber); ~Session(); Session(const Session&) = delete; @@ -74,11 +75,12 @@ class Session : public std::enable_shared_from_this /// @brief returns user context object, usualy a pointer to the authenticated user object std::shared_ptr getUserContext(); - /// @brief returns a string with the address in the format IP:port of the connection endpoint associated with the session. - /// for a client-side session, it returns the server address (e.g., 127.0.0.1:7420). - /// for a server-side session, it returns the address of the connected client (e.g., 127.0.0.1:53124). + /// @brief returns a string with the IP address of the connection endpoint associated with the session. std::string getEndpointAddress(); + /// @brief returns a port number of the connection endpoint associated with the session. + boost::asio::ip::port_type getEndpointPortNumber(); + /// @brief sets a callback to be called when the write operation has not been scheduled due to a timeout reached /// @param writeTaskTimeoutHandler callback void setWriteTimedOutHandler(OnSessionErrorCallback writeTaskTimeoutHandler); @@ -124,8 +126,11 @@ class Session : public std::enable_shared_from_this /// @brief interval of sending the websocket pongs std::chrono::milliseconds heartbeatPeriod; - /// @brief string with the address in the format IP:port of the connection endpoint associated with the session + /// @brief string with the IP address in the format IP:port of the connection endpoint associated with the session std::string endpointAddress; + + /// @brief port number of the connection endpoint associated with the session + boost::asio::ip::port_type endpointPortNumber; }; END_NAMESPACE_NATIVE_STREAMING diff --git a/src/client.cpp b/src/client.cpp index 7d7fc3d..8d85c4d 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -157,10 +157,12 @@ void Client::onUpgradeConnection(const boost::system::error_code& ec, std::share } std::string endpointAddress; + boost::asio::ip::port_type endpointPortNumber; try { auto remoteEp = wsStream->next_layer().socket().remote_endpoint(); - endpointAddress = remoteEp.address().to_string() + ":" + std::to_string(remoteEp.port()); + endpointAddress = remoteEp.address().to_string(); + endpointPortNumber = remoteEp.port(); } catch (const std::exception& e) { @@ -168,13 +170,15 @@ void Client::onUpgradeConnection(const boost::system::error_code& ec, std::share return; } - onNewSessionCallback(createSession(wsStream, endpointAddress)); + onNewSessionCallback(createSession(wsStream, endpointAddress, endpointPortNumber)); } -std::shared_ptr Client::createSession(std::shared_ptr wsStream, const std::string& endpointAddress) +std::shared_ptr Client::createSession(std::shared_ptr wsStream, + const std::string& endpointAddress, + const boost::asio::ip::port_type& endpointPortNumber) { websocketStream.reset(); - return std::make_shared(ioContextPtr, wsStream, nullptr, boost::beast::role_type::client, logCallback, endpointAddress); + return std::make_shared(ioContextPtr, wsStream, nullptr, boost::beast::role_type::client, logCallback, endpointAddress, endpointPortNumber); } END_NAMESPACE_NATIVE_STREAMING diff --git a/src/server.cpp b/src/server.cpp index 54e37fe..679bda0 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -213,6 +213,7 @@ void Server::onUpgradeConnection(const boost::system::error_code& ec, // it throws an exception when attempting to retrieve the endpoint address. // To handle this, first verify the socket state and then safely attempt to retrieve the endpoint name. std::string endpointAddress; + boost::asio::ip::port_type endpointPortNumber; if (!(wsStream->is_open() && wsStream->next_layer().socket().is_open())) { NS_LOG_W("Websocket connection aborted: the socket is already closed"); @@ -223,7 +224,8 @@ void Server::onUpgradeConnection(const boost::system::error_code& ec, try { auto remoteEp = wsStream->next_layer().socket().remote_endpoint(); - endpointAddress = remoteEp.address().to_string() + ":" + std::to_string(remoteEp.port()); + endpointAddress = remoteEp.address().to_string(); + endpointPortNumber = remoteEp.port(); } catch (const std::exception& e) { @@ -233,14 +235,15 @@ void Server::onUpgradeConnection(const boost::system::error_code& ec, } NS_LOG_I("Client {} - websocket connection accepted", endpointAddress); - onNewSessionCallback(createSession(wsStream, userContext, endpointAddress)); + onNewSessionCallback(createSession(wsStream, userContext, endpointAddress, endpointPortNumber)); } std::shared_ptr Server::createSession(std::shared_ptr wsStream, const std::shared_ptr& userContext, - const std::string& endpointAddress) + const std::string& endpointAddress, + const boost::asio::ip::port_type& endpointPortNumber) { - return std::make_shared(ioContextPtr, wsStream, userContext, boost::beast::role_type::server, logCallback, endpointAddress); + return std::make_shared(ioContextPtr, wsStream, userContext, boost::beast::role_type::server, logCallback, endpointAddress, endpointPortNumber); } END_NAMESPACE_NATIVE_STREAMING diff --git a/src/session.cpp b/src/session.cpp index a501b9f..c0da1e3 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -10,7 +10,8 @@ Session::Session(std::shared_ptr ioContextPtr, std::shared_ptr userContext, boost::beast::role_type role, LogCallback logCallback, - const std::string& endpointAddress) + const std::string& endpointAddress, + const boost::asio::ip::port_type& endpointPortNumber) : role(role) , logCallback(logCallback) , ioContextPtr(ioContextPtr) @@ -21,6 +22,7 @@ Session::Session(std::shared_ptr ioContextPtr, , heartbeatTimer(std::make_shared(*ioContextPtr.get())) , heartbeatPeriod(defaultHeartbeatPeriod) , endpointAddress(endpointAddress) + , endpointPortNumber(endpointPortNumber) { setOptions(); } @@ -178,6 +180,11 @@ std::string Session::getEndpointAddress() return endpointAddress; } +boost::asio::ip::port_type Session::getEndpointPortNumber() +{ + return endpointPortNumber; +} + void Session::setWriteTimedOutHandler(OnSessionErrorCallback writeTaskTimeoutHandler) { writer->setWriteTimedOutHandler( diff --git a/test/test_connection.cpp b/test/test_connection.cpp index 1e710d0..a0e35ba 100644 --- a/test/test_connection.cpp +++ b/test/test_connection.cpp @@ -27,7 +27,8 @@ TEST_F(ConnectionTest, Connect) ASSERT_TRUE(serverSession.operator bool()); ASSERT_TRUE(clientSession.operator bool()); - ASSERT_EQ(clientSession->getEndpointAddress(), std::string(CONNECTION_HOST) + std::string(":") + std::to_string(CONNECTION_PORT)); + ASSERT_EQ(clientSession->getEndpointAddress(), std::string(CONNECTION_HOST)); + ASSERT_EQ(clientSession->getEndpointPortNumber(), CONNECTION_PORT); serverSession.reset(); clientSession.reset(); @@ -95,7 +96,8 @@ TEST_F(ConnectionTest, ConnectIPv6) ASSERT_TRUE(serverSession.operator bool()); ASSERT_TRUE(clientSession.operator bool()); - ASSERT_EQ(clientSession->getEndpointAddress(), std::string("::1") + std::string(":") + std::to_string(CONNECTION_PORT)); + ASSERT_EQ(clientSession->getEndpointAddress(), std::string("::1")); + ASSERT_EQ(clientSession->getEndpointPortNumber(), CONNECTION_PORT); serverSession.reset(); clientSession.reset();