Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Added <max_connections> to the websocket server #40

Merged
merged 2 commits into from
Jul 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/websocket.ign
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
<authorization_key>auth_key</authorization_key>
<admin_authorization_key>admin_key</admin_authorization_key>

<!-- The maximum number of allowed connections. If this element is not
defined or negative, then a limit is not enforced. -->
<max_connections>0</max_connections>

<!-- SSL configuration -->
<!-- Specify the path to both the certificate and private key. -->
<!-- Sample self-signed SSL certifacts are located in the
Expand Down
38 changes: 38 additions & 0 deletions plugins/websocket_server/WebsocketServer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ int rootCallback(struct lws *_wsi,
// std::lock_guard<std::mutex> mainLock(self->mutex);
switch (_reason)
{
// Filter network connections.
case LWS_CALLBACK_FILTER_NETWORK_CONNECTION:
// Prevent too many connections.
if (self->maxConnections >= 0 &&
self->connections.size()+1 > self->maxConnections)
{
ignerr << "Skipping new connection, limit of "
<< self->maxConnections << " has been reached\n";
// Return non-zero to close the connection.
return -1;
}
break;

// Open connections.
case LWS_CALLBACK_ESTABLISHED:
igndbg << "LWS_CALLBACK_ESTABLISHED\n";
Expand Down Expand Up @@ -214,6 +227,23 @@ bool WebsocketServer::Load(const tinyxml2::XMLElement *_elem)
}
igndbg << "Using port[" << port << "]\n";

// Get the maximum connection count, if present.
elem = _elem->FirstChildElement("max_connections");
if (elem)
{
try
{
this->maxConnections = std::stoi(elem->GetText());
}
catch (...)
{
ignerr << "Failed to convert port[" << elem->GetText() << "] to integer."
<< std::endl;
}
igndbg << "Using maximum connection count of "
<< this->maxConnections << std::endl;
}

std::string sslCertFile = "";
std::string sslPrivateKeyFile = "";
elem = _elem->FirstChildElement("ssl");
Expand Down Expand Up @@ -374,6 +404,10 @@ void WebsocketServer::OnConnect(int _socketId)
//////////////////////////////////////////////////
void WebsocketServer::OnDisconnect(int _socketId)
{
// Skip invalid sockets
if (this->connections.find(_socketId) == this->connections.end())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add the comment Skip invalid sockets here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in a30524b

return;

this->connections.erase(_socketId);

// Somewhat slow operation.
Expand All @@ -393,6 +427,10 @@ void WebsocketServer::OnDisconnect(int _socketId)
//////////////////////////////////////////////////
void WebsocketServer::OnMessage(int _socketId, const std::string &_msg)
{
// Skip invalid sockets
if (this->connections.find(_socketId) == this->connections.end())
return;

// Frame: operation,topic,type,payload
std::vector<std::string> frameParts = common::split(_msg, ",");

Expand Down
10 changes: 10 additions & 0 deletions plugins/websocket_server/WebsocketServer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,13 @@ namespace ignition
const size_t _size,
const ignition::transport::MessageInfo &_info);

/// \brief Callback that is triggered when a new connection is
/// established.
/// \param[in] _socketId ID of the socket.
public: void OnConnect(int _socketId);

/// \brief Callback that is triggered when a connection ended.
/// \param[in] _socketId ID of the socket.
public: void OnDisconnect(int _socketId);

public: void OnMessage(int _socketId, const std::string &_msg);
Expand Down Expand Up @@ -201,6 +207,10 @@ namespace ignition
/// run loop.
public: int messageCount{0};

/// \brief The maximum number of connections. A negative number
/// indicates no limit.
public: int maxConnections{-1};

/// \brief Time of last publication for each subscribed topic. The key
/// is the topic name and the value the time of last publication.
/// \sa publishPeriod.
Expand Down