|
|
|
@ -86,32 +86,40 @@ struct PerSocketData {
|
|
|
|
|
std::mutex wsMutex;
|
|
|
|
|
std::vector<uWS::WebSocket<false, true, PerSocketData>*> activeWebSockets;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SendFramesToAllClients() {
|
|
|
|
|
std::lock_guard<std::mutex> lock(wsMutex);
|
|
|
|
|
for (auto ws : activeWebSockets) {
|
|
|
|
|
for (int type = 0; type < ST_MAX; ++type) {
|
|
|
|
|
cv::Mat frame;
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(frameQueues[type].frameMutex);
|
|
|
|
|
if (!frameQueues[type].frameQueue.empty()) {
|
|
|
|
|
frame = frameQueues[type].frameQueue.front();
|
|
|
|
|
frameQueues[type].frameQueue.pop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
std::string message;
|
|
|
|
|
cv::Mat originalFrame, maskedFrame;
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(frameQueues[ST_ORIGINAL].frameMutex);
|
|
|
|
|
if (!frameQueues[ST_ORIGINAL].frameQueue.empty()) {
|
|
|
|
|
originalFrame = frameQueues[ST_ORIGINAL].frameQueue.front();
|
|
|
|
|
frameQueues[ST_ORIGINAL].frameQueue.pop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(frameQueues[ST_MASKED].frameMutex);
|
|
|
|
|
if (!frameQueues[ST_MASKED].frameQueue.empty()) {
|
|
|
|
|
maskedFrame = frameQueues[ST_MASKED].frameQueue.front();
|
|
|
|
|
frameQueues[ST_MASKED].frameQueue.pop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!frame.empty()) {
|
|
|
|
|
std::vector<uchar> jpeg = matToJpeg(frame);
|
|
|
|
|
uint32_t size = jpeg.size();
|
|
|
|
|
if (!originalFrame.empty() && !maskedFrame.empty()) {
|
|
|
|
|
std::vector<uchar> originalJpeg = matToJpeg(originalFrame);
|
|
|
|
|
std::vector<uchar> maskedJpeg = matToJpeg(maskedFrame);
|
|
|
|
|
|
|
|
|
|
// Prepare the message: type (1 byte) + size (4 bytes) + image data
|
|
|
|
|
std::string message(1, static_cast<char>(type));
|
|
|
|
|
message.append(reinterpret_cast<char*>(&size), 4);
|
|
|
|
|
message.append(jpeg.begin(), jpeg.end());
|
|
|
|
|
uint32_t originalSize = originalJpeg.size();
|
|
|
|
|
uint32_t maskedSize = maskedJpeg.size();
|
|
|
|
|
|
|
|
|
|
ws->send(message, uWS::OpCode::BINARY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Prepare the message: originalSize (4 bytes) + maskedSize (4 bytes) + original image data + masked image data
|
|
|
|
|
message.append(reinterpret_cast<char*>(&originalSize), 4);
|
|
|
|
|
message.append(reinterpret_cast<char*>(&maskedSize), 4);
|
|
|
|
|
message.append(originalJpeg.begin(), originalJpeg.end());
|
|
|
|
|
message.append(maskedJpeg.begin(), maskedJpeg.end());
|
|
|
|
|
}
|
|
|
|
|
for (auto ws : activeWebSockets) {
|
|
|
|
|
ws->send(message, uWS::OpCode::BINARY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -133,9 +141,10 @@ void RunWebSocketServer(int websocketPort) {
|
|
|
|
|
.resetIdleTimeoutOnSend = false,
|
|
|
|
|
.sendPingsAutomatically = true,
|
|
|
|
|
.open = [](auto* ws) {
|
|
|
|
|
Logger("WebSocket connection opened\n");
|
|
|
|
|
Logger("WebSocket connection opened, current connections: %d\n", activeWebSockets.size() + 1);
|
|
|
|
|
std::lock_guard<std::mutex> lock(wsMutex);
|
|
|
|
|
activeWebSockets.push_back(ws);
|
|
|
|
|
Logger("Client address: %s\n", ws->getRemoteAddressAsText().data());
|
|
|
|
|
},
|
|
|
|
|
.message = [](auto* ws, std::string_view message, uWS::OpCode opCode) {
|
|
|
|
|
// Handle incoming messages if needed
|
|
|
|
|