Skip to content

Commit

Permalink
Server working.
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrien4193 committed May 27, 2024
1 parent 0f2fac8 commit 8a92f7e
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 81 deletions.
6 changes: 3 additions & 3 deletions src/brayns/core/jsonv2/JsonValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const JsonArray &getArray(const JsonValue &json)
}
catch (const Poco::Exception &e)
{
throw JsonException(e.displayText());
throw JsonException(e.message());
}
}

Expand All @@ -68,7 +68,7 @@ const JsonObject &getObject(const JsonValue &json)
}
catch (const Poco::Exception &e)
{
throw JsonException(e.displayText());
throw JsonException(e.message());
}
}

Expand All @@ -88,7 +88,7 @@ JsonValue parseJson(const std::string &data)
}
catch (const Poco::Exception &e)
{
throw JsonException(e.displayText());
throw JsonException(e.message());
}
}
}
2 changes: 1 addition & 1 deletion src/brayns/core/utils/Binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ T swapBytes(T value)
inline std::string_view extractBytes(std::string_view &bytes, std::size_t count)
{
auto extracted = bytes.substr(0, count);
bytes.remove_prefix(count);
bytes.remove_prefix(extracted.size());
return extracted;
}

Expand Down
15 changes: 1 addition & 14 deletions src/brayns/core/utils/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,6 @@

#include "Log.h"

#include <iostream>

namespace
{
using namespace brayns;

Logger consoleLogger()
{
auto handler = [](const auto &record) { std::cout << toString(record) << '\n'; };
return Logger("Brayns", LogLevel::Info, handler);
}
}

namespace brayns
{
void Log::setLevel(LogLevel level)
Expand All @@ -46,5 +33,5 @@ void Log::disable()
setLevel(LogLevel::Off);
}

Logger Log::_logger = consoleLogger();
Logger Log::_logger = createConsoleLogger("Brayns");
} // namespace brayns
7 changes: 7 additions & 0 deletions src/brayns/core/utils/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "Logger.h"

#include <iostream>
#include <stdexcept>

namespace brayns
Expand Down Expand Up @@ -71,4 +72,10 @@ bool Logger::isEnabled(LogLevel level) const
{
return level >= _level;
}

Logger createConsoleLogger(std::string name)
{
auto handler = [](const auto &record) { std::cout << toString(record) << '\n'; };
return Logger(std::move(name), LogLevel::Info, handler);
}
}
2 changes: 2 additions & 0 deletions src/brayns/core/utils/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,6 @@ class Logger
LogLevel _level;
LogHandler _handler;
};

Logger createConsoleLogger(std::string name);
}
18 changes: 12 additions & 6 deletions src/brayns/core/websocket/WebSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ WebSocketFrame receiveFrame(Poco::Net::WebSocket &websocket)

websocket.receiveFrame(buffer, flags);

if (flags == 0 && buffer.size() == 0)
{
throw WebSocketClosed("Empty frame received");
}

auto finalFrame = flags & Poco::Net::WebSocket::FRAME_FLAG_FIN;

auto opcode = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
Expand Down Expand Up @@ -79,7 +84,7 @@ WebSocketStatus getStatus(int errorCode)
WebSocketException websocketException(const Poco::Exception &e)
{
auto status = getStatus(e.code());
auto message = e.displayText();
const auto &message = e.message();
return WebSocketException(status, message);
}
}
Expand All @@ -102,6 +107,12 @@ WebSocket::WebSocket(const Poco::Net::WebSocket &websocket):
{
}

std::size_t WebSocket::getMaxFrameSize() const
{
auto size = _websocket.getMaxPayloadSize();
return static_cast<std::size_t>(size);
}

WebSocketFrame WebSocket::receive()
{
try
Expand Down Expand Up @@ -147,9 +158,4 @@ void WebSocket::close(WebSocketStatus status, std::string_view message)
{
}
}

void WebSocket::close(const WebSocketException &e)
{
close(e.getStatus(), e.what());
}
}
8 changes: 7 additions & 1 deletion src/brayns/core/websocket/WebSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ class WebSocketException : public std::runtime_error
WebSocketStatus _status;
};

class WebSocketClosed : public std::runtime_error
{
public:
using runtime_error::runtime_error;
};

enum class WebSocketOpcode
{
Continuation = Poco::Net::WebSocket::FRAME_OP_CONT,
Expand Down Expand Up @@ -77,10 +83,10 @@ class WebSocket
public:
explicit WebSocket(const Poco::Net::WebSocket &websocket);

std::size_t getMaxFrameSize() const;
WebSocketFrame receive();
void send(const WebSocketFrameView &frame);
void close(WebSocketStatus status, std::string_view message = {});
void close(const WebSocketException &e);

private:
Poco::Net::WebSocket _websocket;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "WebSocketManager.h"
#include "WebSocketHandler.h"

#include <string>
#include <utility>

#include <brayns/core/utils/Binary.h>

namespace
{
using namespace brayns::experimental;
using namespace brayns;
using brayns::Logger;

struct WebSocketBuffer
{
Expand Down Expand Up @@ -73,38 +75,71 @@ void onBinary(const WebSocketFrame &frame, WebSocketBuffer &buffer, Logger &logg
buffer.binary = true;
}

void onClose(const WebSocketConnection &websocket, Logger &logger)
void onClose(WebSocket &websocket, Logger &logger)
{
logger.info("Close frame received, sending normal close frame");

websocket.closeOk();
websocket.close(WebSocketStatus::NormalClose);
}

void onPing(const WebSocketConnection &websocket, Logger &logger)
void onPing(const WebSocketFrame &frame, WebSocket &websocket, Logger &logger)
{
logger.info("Ping frame received, sending pong frame");

websocket.send({.opcode = WebSocketOpcode::Pong});
websocket.send({.opcode = WebSocketOpcode::Pong, .data = frame.data});
}

void onPong(Logger &logger)
{
logger.info("Pong frame received, ignoring");
}

void respond(const WebSocketConnection &websocket, const RawResponse &response)
void respond(ClientId clientId, WebSocket &websocket, Logger &logger, const RawResponse &response)
{
websocket.send({
.opcode = response.binary ? WebSocketOpcode::Binary : WebSocketOpcode::Text,
.data = response.data,
});
auto data = response.data;

logger.info("Sending response of {} bytes to client {}", data.size(), clientId);

if (!response.binary)
{
logger.debug("Text response data: {}", data);
}

auto opcode = response.binary ? WebSocketOpcode::Binary : WebSocketOpcode::Text;

auto maxFrameSize = websocket.getMaxFrameSize();

while (true)
{
auto chunk = extractBytes(data, maxFrameSize);

logger.info("Sending websocket frame of {} bytes", data.size());

try
{
websocket.send({opcode, chunk});
}
catch (const WebSocketException &e)
{
logger.warn("Failed to send websocket frame: {}", e.what());
websocket.close(e.getStatus(), e.what());
return;
}
catch (...)
{
logger.error("Unexpected error while sending websocket frame");
websocket.close(WebSocketStatus::UnexpectedCondition, "Internal error");
return;
}

if (data.empty())
{
return;
}
}
}

void runClientLoop(
ClientId clientId,
const WebSocketConnection &websocket,
const WebSocketListener &listener,
Logger &logger)
void runClientLoop(ClientId clientId, WebSocket &websocket, const WebSocketListener &listener, Logger &logger)
{
auto buffer = WebSocketBuffer();

Expand All @@ -127,12 +162,13 @@ void runClientLoop(
onClose(websocket, logger);
return;
case WebSocketOpcode::Ping:
onPing(websocket, logger);
onPing(frame, websocket, logger);
continue;
case WebSocketOpcode::Pong:
onPong(logger);
continue;
default:
logger.error("Unexpected invalid opcode: {}", static_cast<int>(frame.opcode));
throw WebSocketException(WebSocketStatus::UnexpectedCondition, "Unexpected invalid opcode");
}

Expand All @@ -141,37 +177,55 @@ void runClientLoop(
continue;
}

listener.onRequest({
auto request = RawRequest{
.clientId = clientId,
.data = std::exchange(buffer.data, {}),
.binary = buffer.binary,
.respond = [=](const auto &response) { respond(websocket, response); },
});
.respond = [=, &logger](const auto &response) mutable { respond(clientId, websocket, logger, response); },
};

logger.info("Received request of {} bytes from client {}", request.data.size(), clientId);

if (!request.binary)
{
logger.debug("Text request data: {}", request.data);
}

listener.onRequest(request);
}
}
}

namespace brayns::experimental
{
WebSocketManager::WebSocketManager(WebSocketListener listener, Logger &logger):
WebSocketHandler::WebSocketHandler(WebSocketListener listener, Logger &logger):
_listener(std::move(listener)),
_logger(&logger)
{
}

void WebSocketManager::handle(const WebSocketConnection &websocket)
void WebSocketHandler::handle(WebSocket &websocket)
{
auto clientId = _clientIds.next();

_listener.onConnect(clientId);

try
{
runClientLoop(clientId, websocket, _listener, *_logger);
}
catch (...)
catch (const WebSocketClosed &e)
{
_logger->warn("WebSocket closed by peer: {}", e.what());
}
catch (const WebSocketException &e)
{
_logger->error("Unexpected error in websocket client loop");
_logger->warn("Error while processing websocket: '{}'", e.what());
websocket.close(e.getStatus(), e.what());
}

_listener.onDisconnect(clientId);

_clientIds.recycle(clientId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@

namespace brayns::experimental
{
struct WebSocketConnection
{
std::function<WebSocketFrame()> receive;
std::function<void(const WebSocketFrameView &)> send;
std::function<void()> closeOk;
};

using ClientId = std::uint32_t;

struct RawResponse
Expand All @@ -62,12 +55,12 @@ struct WebSocketListener
std::function<void(RawRequest)> onRequest;
};

class WebSocketManager
class WebSocketHandler
{
public:
explicit WebSocketManager(WebSocketListener listener, Logger &logger);
explicit WebSocketHandler(WebSocketListener listener, Logger &logger);

void handle(const WebSocketConnection &websocket);
void handle(WebSocket &websocket);

private:
WebSocketListener _listener;
Expand Down
Loading

0 comments on commit 8a92f7e

Please sign in to comment.