IXWebSocket/ixwebsocket/IXWebSocketServer.cpp

172 lines
4.9 KiB
C++
Raw Normal View History

2018-12-30 08:15:27 +01:00
/*
* IXWebSocketServer.cpp
* Author: Benjamin Sergeant
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*/
#include "IXWebSocketServer.h"
2019-09-23 19:25:23 +02:00
#include "IXNetSystem.h"
#include "IXSetThreadName.h"
2019-09-23 19:25:23 +02:00
#include "IXSocketConnect.h"
#include "IXWebSocket.h"
#include "IXWebSocketTransport.h"
2019-01-01 22:47:25 +01:00
#include <future>
2019-09-23 19:25:23 +02:00
#include <sstream>
2019-01-02 02:13:26 +01:00
#include <string.h>
2018-12-30 08:15:27 +01:00
namespace ix
2018-12-30 08:15:27 +01:00
{
2019-01-04 03:33:08 +01:00
const int WebSocketServer::kDefaultHandShakeTimeoutSecs(3); // 3 seconds
const bool WebSocketServer::kDefaultEnablePong(true);
WebSocketServer::WebSocketServer(int port,
const std::string& host,
int backlog,
2019-01-04 03:33:08 +01:00
size_t maxConnections,
int handshakeTimeoutSecs,
int addressFamily)
: SocketServer(port, host, backlog, maxConnections, addressFamily)
2019-09-23 19:25:23 +02:00
, _handshakeTimeoutSecs(handshakeTimeoutSecs)
, _enablePong(kDefaultEnablePong)
, _enablePerMessageDeflate(true)
2018-12-30 08:15:27 +01:00
{
}
WebSocketServer::~WebSocketServer()
{
stop();
2018-12-30 08:15:27 +01:00
}
void WebSocketServer::stop()
{
stopAcceptingConnections();
auto clients = getClients();
for (auto client : clients)
{
client->close();
}
SocketServer::stop();
}
void WebSocketServer::enablePong()
{
_enablePong = true;
}
void WebSocketServer::disablePong()
{
_enablePong = false;
}
void WebSocketServer::disablePerMessageDeflate()
{
_enablePerMessageDeflate = false;
}
void WebSocketServer::setOnConnectionCallback(const OnConnectionCallback& callback)
{
_onConnectionCallback = callback;
}
void WebSocketServer::setOnClientMessageCallback(const OnClientMessageCallback& callback)
{
_onClientMessageCallback = callback;
}
2020-03-24 20:40:58 +01:00
void WebSocketServer::handleConnection(std::unique_ptr<Socket> socket,
std::shared_ptr<ConnectionState> connectionState)
{
setThreadName("WebSocketServer::" + connectionState->getId());
auto webSocket = std::make_shared<WebSocket>();
if (_onConnectionCallback)
{
_onConnectionCallback(webSocket, connectionState);
if (!webSocket->isOnMessageCallbackRegistered())
{
logError("WebSocketServer Application developer error: Server callback improperly "
"registerered.");
logError("Missing call to setOnMessageCallback inside setOnConnectionCallback.");
connectionState->setTerminated();
return;
}
}
else if (_onClientMessageCallback)
{
webSocket->setOnMessageCallback(
[this, &ws = *webSocket.get(), connectionState](const WebSocketMessagePtr& msg) {
_onClientMessageCallback(connectionState, ws, msg);
});
}
else
{
logError(
"WebSocketServer Application developer error: No server callback is registerered.");
logError("Missing call to setOnConnectionCallback or setOnClientMessageCallback.");
connectionState->setTerminated();
return;
}
webSocket->disableAutomaticReconnection();
if (_enablePong)
{
webSocket->enablePong();
}
else
{
webSocket->disablePong();
}
// Add this client to our client set
{
std::lock_guard<std::mutex> lock(_clientsMutex);
_clients.insert(webSocket);
}
2019-01-01 22:47:25 +01:00
2020-03-24 20:40:58 +01:00
auto status = webSocket->connectToSocket(std::move(socket), _handshakeTimeoutSecs);
if (status.success)
{
// Process incoming messages and execute callbacks
// until the connection is closed
webSocket->run();
}
else
2019-01-01 22:47:25 +01:00
{
std::stringstream ss;
2019-09-23 19:25:23 +02:00
ss << "WebSocketServer::handleConnection() HTTP status: " << status.http_status
<< " error: " << status.errorStr;
logError(ss.str());
2019-01-01 22:47:25 +01:00
}
webSocket->setOnMessageCallback(nullptr);
// Remove this client from our client set
{
std::lock_guard<std::mutex> lock(_clientsMutex);
if (_clients.erase(webSocket) != 1)
{
logError("Cannot delete client");
}
}
connectionState->setTerminated();
}
2019-01-01 22:47:25 +01:00
std::set<std::shared_ptr<WebSocket>> WebSocketServer::getClients()
{
std::lock_guard<std::mutex> lock(_clientsMutex);
return _clients;
2018-12-30 08:15:27 +01:00
}
size_t WebSocketServer::getConnectedClientsCount()
{
std::lock_guard<std::mutex> lock(_clientsMutex);
return _clients.size();
}
2019-09-23 19:25:23 +02:00
} // namespace ix