Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
21758f1183 | |||
422febf15d | |||
51ec32405d | |||
6a90dc7259 | |||
262f32857f | |||
91fb3992ac | |||
e8b12feaeb | |||
730fbc5b31 |
@ -5,7 +5,7 @@ include(FindPackageHandleStandardArgs)
|
|||||||
find_path(DEFLATE_INCLUDE_DIRS libdeflate.h)
|
find_path(DEFLATE_INCLUDE_DIRS libdeflate.h)
|
||||||
find_library(DEFLATE_LIBRARY deflate)
|
find_library(DEFLATE_LIBRARY deflate)
|
||||||
|
|
||||||
find_package_handle_standard_args(DEFLATE
|
find_package_handle_standard_args(Deflate
|
||||||
FOUND_VAR
|
FOUND_VAR
|
||||||
DEFLATE_FOUND
|
DEFLATE_FOUND
|
||||||
REQUIRED_VARS
|
REQUIRED_VARS
|
||||||
|
@ -203,7 +203,7 @@ if (USE_ZLIB)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# brew install libdeflate
|
# brew install libdeflate
|
||||||
find_package(DEFLATE)
|
find_package(Deflate)
|
||||||
if (DEFLATE_FOUND)
|
if (DEFLATE_FOUND)
|
||||||
include_directories(${DEFLATE_INCLUDE_DIRS})
|
include_directories(${DEFLATE_INCLUDE_DIRS})
|
||||||
target_link_libraries(ixwebsocket ${DEFLATE_LIBRARIES})
|
target_link_libraries(ixwebsocket ${DEFLATE_LIBRARIES})
|
||||||
@ -264,7 +264,8 @@ if (USE_WS OR USE_TEST)
|
|||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(spdlog
|
FetchContent_Declare(spdlog
|
||||||
GIT_REPOSITORY "https://github.com/gabime/spdlog"
|
GIT_REPOSITORY "https://github.com/gabime/spdlog"
|
||||||
GIT_TAG "v1.8.0")
|
GIT_TAG "v1.8.0"
|
||||||
|
GIT_SHALLOW 1)
|
||||||
|
|
||||||
FetchContent_MakeAvailable(spdlog)
|
FetchContent_MakeAvailable(spdlog)
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ If your company or project is using this library, feel free to open an issue or
|
|||||||
- [libDiscordBot](https://github.com/tostc/libDiscordBot/tree/master), an easy to use Discord-bot framework.
|
- [libDiscordBot](https://github.com/tostc/libDiscordBot/tree/master), an easy to use Discord-bot framework.
|
||||||
- [gwebsocket](https://github.com/norrbotten/gwebsocket), a websocket (lua) module for Garry's Mod
|
- [gwebsocket](https://github.com/norrbotten/gwebsocket), a websocket (lua) module for Garry's Mod
|
||||||
- [DisCPP](https://github.com/DisCPP/DisCPP), a simple but feature rich Discord API wrapper
|
- [DisCPP](https://github.com/DisCPP/DisCPP), a simple but feature rich Discord API wrapper
|
||||||
|
- [discord.cpp](https://github.com/luccanunes/discord.cpp), a discord library for making bots
|
||||||
|
|
||||||
## Continuous Integration
|
## Continuous Integration
|
||||||
|
|
||||||
|
@ -2,6 +2,26 @@
|
|||||||
|
|
||||||
All changes to this project will be documented in this file.
|
All changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [11.0.0] - 2020-11-11
|
||||||
|
|
||||||
|
(openssl security fix) in the client to server connection, peer verification is not done in all cases. See https://github.com/machinezone/IXWebSocket/pull/250
|
||||||
|
|
||||||
|
## [10.5.7] - 2020-11-07
|
||||||
|
|
||||||
|
(docker) build docker container with zlib disabled
|
||||||
|
|
||||||
|
## [10.5.6] - 2020-11-07
|
||||||
|
|
||||||
|
(cmake) DEFLATE -> Deflate in CMake to stop warnings about casing
|
||||||
|
|
||||||
|
## [10.5.5] - 2020-11-07
|
||||||
|
|
||||||
|
(ws autoroute) Display result in compliant way (AUTOROUTE IXWebSocket :: N ms) so that result can be parsed easily
|
||||||
|
|
||||||
|
## [10.5.4] - 2020-10-30
|
||||||
|
|
||||||
|
(ws gunzip + IXGZipCodec) Can decompress gziped data with libdeflate. ws gunzip computed output filename was incorrect (was the extension aka gz) instead of the file without the extension. Also check whether the output file is writeable.
|
||||||
|
|
||||||
## [10.5.3] - 2020-10-19
|
## [10.5.3] - 2020-10-19
|
||||||
|
|
||||||
(http code) With zlib disabled, some code should not be reached
|
(http code) With zlib disabled, some code should not be reached
|
||||||
|
@ -20,9 +20,11 @@
|
|||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
#ifdef IXWEBSOCKET_USE_ZLIB
|
|
||||||
std::string gzipCompress(const std::string& str)
|
std::string gzipCompress(const std::string& str)
|
||||||
{
|
{
|
||||||
|
#ifndef IXWEBSOCKET_USE_ZLIB
|
||||||
|
return std::string();
|
||||||
|
#else
|
||||||
#ifdef IXWEBSOCKET_USE_DEFLATE
|
#ifdef IXWEBSOCKET_USE_DEFLATE
|
||||||
int compressionLevel = 6;
|
int compressionLevel = 6;
|
||||||
struct libdeflate_compressor* compressor;
|
struct libdeflate_compressor* compressor;
|
||||||
@ -99,11 +101,43 @@ namespace ix
|
|||||||
deflateEnd(&zs);
|
deflateEnd(&zs);
|
||||||
|
|
||||||
return outstring;
|
return outstring;
|
||||||
#endif
|
#endif // IXWEBSOCKET_USE_DEFLATE
|
||||||
|
#endif // IXWEBSOCKET_USE_ZLIB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef IXWEBSOCKET_USE_DEFLATE
|
||||||
|
static uint32_t loadDecompressedGzipSize(const uint8_t* p)
|
||||||
|
{
|
||||||
|
return ((uint32_t) p[0] << 0) | ((uint32_t) p[1] << 8) | ((uint32_t) p[2] << 16) |
|
||||||
|
((uint32_t) p[3] << 24);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool gzipDecompress(const std::string& in, std::string& out)
|
bool gzipDecompress(const std::string& in, std::string& out)
|
||||||
{
|
{
|
||||||
|
#ifndef IXWEBSOCKET_USE_ZLIB
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
#ifdef IXWEBSOCKET_USE_DEFLATE
|
||||||
|
struct libdeflate_decompressor* decompressor;
|
||||||
|
decompressor = libdeflate_alloc_decompressor();
|
||||||
|
|
||||||
|
const void* compressed_data = in.data();
|
||||||
|
size_t compressed_size = in.size();
|
||||||
|
|
||||||
|
// Retrieve uncompressed size from the trailer of the gziped data
|
||||||
|
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&in.front());
|
||||||
|
auto uncompressed_size = loadDecompressedGzipSize(&ptr[compressed_size - 4]);
|
||||||
|
|
||||||
|
// Use it to redimension our output buffer
|
||||||
|
out.resize(uncompressed_size);
|
||||||
|
|
||||||
|
libdeflate_result result = libdeflate_gzip_decompress(
|
||||||
|
decompressor, compressed_data, compressed_size, &out.front(), uncompressed_size, NULL);
|
||||||
|
|
||||||
|
libdeflate_free_decompressor(decompressor);
|
||||||
|
return result == LIBDEFLATE_SUCCESS;
|
||||||
|
#else
|
||||||
z_stream inflateState;
|
z_stream inflateState;
|
||||||
memset(&inflateState, 0, sizeof(inflateState));
|
memset(&inflateState, 0, sizeof(inflateState));
|
||||||
|
|
||||||
@ -143,6 +177,7 @@ namespace ix
|
|||||||
|
|
||||||
inflateEnd(&inflateState);
|
inflateEnd(&inflateState);
|
||||||
return true;
|
return true;
|
||||||
|
#endif // IXWEBSOCKET_USE_DEFLATE
|
||||||
|
#endif // IXWEBSOCKET_USE_ZLIB
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} // namespace ix
|
} // namespace ix
|
||||||
|
@ -503,14 +503,13 @@ namespace ix
|
|||||||
errMsg += ERR_error_string(sslErr, nullptr);
|
errMsg += ERR_error_string(sslErr, nullptr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX_set_verify(
|
|
||||||
_ssl_context, SSL_VERIFY_PEER, [](int preverify, X509_STORE_CTX*) -> int {
|
|
||||||
return preverify;
|
|
||||||
});
|
|
||||||
SSL_CTX_set_verify_depth(_ssl_context, 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSL_CTX_set_verify(_ssl_context,
|
||||||
|
SSL_VERIFY_PEER,
|
||||||
|
[](int preverify, X509_STORE_CTX*) -> int { return preverify; });
|
||||||
|
SSL_CTX_set_verify_depth(_ssl_context, 4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define IX_WEBSOCKET_VERSION "10.5.3"
|
#define IX_WEBSOCKET_VERSION "10.6.0"
|
||||||
|
8
makefile
8
makefile
@ -28,11 +28,14 @@ brew:
|
|||||||
# server side ?) and I can't work-around it easily, so we're using mbedtls on
|
# server side ?) and I can't work-around it easily, so we're using mbedtls on
|
||||||
# Linux for the SSL backend, which works great.
|
# Linux for the SSL backend, which works great.
|
||||||
ws_mbedtls_install:
|
ws_mbedtls_install:
|
||||||
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
|
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_ZLIB=OFF -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
|
||||||
|
|
||||||
ws:
|
ws:
|
||||||
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install)
|
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install)
|
||||||
|
|
||||||
|
ws_unity:
|
||||||
|
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install)
|
||||||
|
|
||||||
ws_install:
|
ws_install:
|
||||||
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. -DUSE_TEST=0 && ninja install)
|
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. -DUSE_TEST=0 && ninja install)
|
||||||
|
|
||||||
@ -247,6 +250,9 @@ doc:
|
|||||||
change: format
|
change: format
|
||||||
vim ixwebsocket/IXWebSocketVersion.h docs/CHANGELOG.md
|
vim ixwebsocket/IXWebSocketVersion.h docs/CHANGELOG.md
|
||||||
|
|
||||||
|
change_no_format:
|
||||||
|
vim ixwebsocket/IXWebSocketVersion.h docs/CHANGELOG.md
|
||||||
|
|
||||||
commit:
|
commit:
|
||||||
git commit -am "`sh tools/extract_latest_change.sh`"
|
git commit -am "`sh tools/extract_latest_change.sh`"
|
||||||
|
|
||||||
|
@ -38,35 +38,6 @@ namespace
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void runPublisher(const ix::CobraConfig& config, const std::string& channel)
|
|
||||||
{
|
|
||||||
ix::CobraMetricsPublisher cobraMetricsPublisher;
|
|
||||||
cobraMetricsPublisher.configure(config, channel);
|
|
||||||
cobraMetricsPublisher.setSession(uuid4());
|
|
||||||
cobraMetricsPublisher.enable(true);
|
|
||||||
|
|
||||||
Json::Value msg;
|
|
||||||
msg["fps"] = 60;
|
|
||||||
|
|
||||||
cobraMetricsPublisher.setGenericAttributes("game", "ody");
|
|
||||||
|
|
||||||
// Wait a bit
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
// publish some messages
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #1)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_B_id", msg); // (msg #2)
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #3)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_D_id", msg); // (msg #4)
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #4)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_F_id", msg); // (msg #5)
|
|
||||||
ix::msleep(500);
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]")
|
TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]")
|
||||||
|
@ -20,38 +20,6 @@
|
|||||||
|
|
||||||
using namespace ix;
|
using namespace ix;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void runPublisher(const ix::CobraConfig& config, const std::string& channel)
|
|
||||||
{
|
|
||||||
ix::CobraMetricsPublisher cobraMetricsPublisher;
|
|
||||||
cobraMetricsPublisher.configure(config, channel);
|
|
||||||
cobraMetricsPublisher.setSession(uuid4());
|
|
||||||
cobraMetricsPublisher.enable(true);
|
|
||||||
|
|
||||||
Json::Value msg;
|
|
||||||
msg["fps"] = 60;
|
|
||||||
|
|
||||||
cobraMetricsPublisher.setGenericAttributes("game", "ody");
|
|
||||||
|
|
||||||
// Wait a bit
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
// publish some messages
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #1)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_B_id", msg); // (msg #2)
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #3)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_D_id", msg); // (msg #4)
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #4)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_F_id", msg); // (msg #5)
|
|
||||||
ix::msleep(500);
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]")
|
TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]")
|
||||||
{
|
{
|
||||||
SECTION("Exchange and count sent/received messages.")
|
SECTION("Exchange and count sent/received messages.")
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ixbots/IXCobraToStdoutBot.h>
|
#include <ixbots/IXCobraToStdoutBot.h>
|
||||||
#include <ixcobra/IXCobraConnection.h>
|
#include <ixcobra/IXCobraConnection.h>
|
||||||
#include <ixcobra/IXCobraMetricsPublisher.h>
|
|
||||||
#include <ixcrypto/IXUuid.h>
|
#include <ixcrypto/IXUuid.h>
|
||||||
#include <ixredis/IXRedisServer.h>
|
#include <ixredis/IXRedisServer.h>
|
||||||
#include <ixsentry/IXSentryClient.h>
|
#include <ixsentry/IXSentryClient.h>
|
||||||
@ -20,38 +19,6 @@
|
|||||||
|
|
||||||
using namespace ix;
|
using namespace ix;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void runPublisher(const ix::CobraConfig& config, const std::string& channel)
|
|
||||||
{
|
|
||||||
ix::CobraMetricsPublisher cobraMetricsPublisher;
|
|
||||||
cobraMetricsPublisher.configure(config, channel);
|
|
||||||
cobraMetricsPublisher.setSession(uuid4());
|
|
||||||
cobraMetricsPublisher.enable(true);
|
|
||||||
|
|
||||||
Json::Value msg;
|
|
||||||
msg["fps"] = 60;
|
|
||||||
|
|
||||||
cobraMetricsPublisher.setGenericAttributes("game", "ody");
|
|
||||||
|
|
||||||
// Wait a bit
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
// publish some messages
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #1)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_B_id", msg); // (msg #2)
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #3)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_D_id", msg); // (msg #4)
|
|
||||||
ix::msleep(500);
|
|
||||||
|
|
||||||
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #4)
|
|
||||||
cobraMetricsPublisher.push("sms_metric_F_id", msg); // (msg #5)
|
|
||||||
ix::msleep(500);
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TEST_CASE("Cobra_to_stdout_bot", "[cobra_bots]")
|
TEST_CASE("Cobra_to_stdout_bot", "[cobra_bots]")
|
||||||
{
|
{
|
||||||
SECTION("Exchange and count sent/received messages.")
|
SECTION("Exchange and count sent/received messages.")
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <ixcobra/IXCobraMetricsPublisher.h>
|
||||||
|
#include <ixcrypto/IXUuid.h>
|
||||||
#include <ixwebsocket/IXNetSystem.h>
|
#include <ixwebsocket/IXNetSystem.h>
|
||||||
#include <ixwebsocket/IXWebSocket.h>
|
#include <ixwebsocket/IXWebSocket.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@ -243,4 +245,33 @@ namespace ix
|
|||||||
|
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runPublisher(const ix::CobraConfig& config, const std::string& channel)
|
||||||
|
{
|
||||||
|
ix::CobraMetricsPublisher cobraMetricsPublisher;
|
||||||
|
cobraMetricsPublisher.configure(config, channel);
|
||||||
|
cobraMetricsPublisher.setSession(uuid4());
|
||||||
|
cobraMetricsPublisher.enable(true);
|
||||||
|
|
||||||
|
Json::Value msg;
|
||||||
|
msg["fps"] = 60;
|
||||||
|
|
||||||
|
cobraMetricsPublisher.setGenericAttributes("game", "ody");
|
||||||
|
|
||||||
|
// Wait a bit
|
||||||
|
ix::msleep(500);
|
||||||
|
|
||||||
|
// publish some messages
|
||||||
|
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #1)
|
||||||
|
cobraMetricsPublisher.push("sms_metric_B_id", msg); // (msg #2)
|
||||||
|
ix::msleep(500);
|
||||||
|
|
||||||
|
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #3)
|
||||||
|
cobraMetricsPublisher.push("sms_metric_D_id", msg); // (msg #4)
|
||||||
|
ix::msleep(500);
|
||||||
|
|
||||||
|
cobraMetricsPublisher.push("sms_metric_A_id", msg); // (msg #4)
|
||||||
|
cobraMetricsPublisher.push("sms_metric_F_id", msg); // (msg #5)
|
||||||
|
ix::msleep(500);
|
||||||
|
}
|
||||||
} // namespace ix
|
} // namespace ix
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <ixcobra/IXCobraConfig.h>
|
||||||
#include <ixsnake/IXAppConfig.h>
|
#include <ixsnake/IXAppConfig.h>
|
||||||
#include <ixwebsocket/IXGetFreePort.h>
|
#include <ixwebsocket/IXGetFreePort.h>
|
||||||
#include <ixwebsocket/IXSocketTLSOptions.h>
|
#include <ixwebsocket/IXSocketTLSOptions.h>
|
||||||
@ -59,4 +60,6 @@ namespace ix
|
|||||||
std::string getWsScheme(bool preferTLS);
|
std::string getWsScheme(bool preferTLS);
|
||||||
|
|
||||||
std::string makeCobraEndpoint(int port, bool preferTLS);
|
std::string makeCobraEndpoint(int port, bool preferTLS);
|
||||||
|
|
||||||
|
void runPublisher(const ix::CobraConfig& config, const std::string& channel);
|
||||||
} // namespace ix
|
} // namespace ix
|
||||||
|
@ -18,10 +18,10 @@ using namespace ix;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class WebSocketChat
|
class WebSocketBroadcastChat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebSocketChat(const std::string& user, const std::string& session, int port);
|
WebSocketBroadcastChat(const std::string& user, const std::string& session, int port);
|
||||||
|
|
||||||
void subscribe(const std::string& channel);
|
void subscribe(const std::string& channel);
|
||||||
void start();
|
void start();
|
||||||
@ -47,7 +47,9 @@ namespace
|
|||||||
mutable std::mutex _mutex;
|
mutable std::mutex _mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
WebSocketChat::WebSocketChat(const std::string& user, const std::string& session, int port)
|
WebSocketBroadcastChat::WebSocketBroadcastChat(const std::string& user,
|
||||||
|
const std::string& session,
|
||||||
|
int port)
|
||||||
: _user(user)
|
: _user(user)
|
||||||
, _session(session)
|
, _session(session)
|
||||||
, _port(port)
|
, _port(port)
|
||||||
@ -55,35 +57,35 @@ namespace
|
|||||||
_webSocket.setTLSOptions(makeClientTLSOptions());
|
_webSocket.setTLSOptions(makeClientTLSOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t WebSocketChat::getReceivedMessagesCount() const
|
size_t WebSocketBroadcastChat::getReceivedMessagesCount() const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
return _receivedMessages.size();
|
return _receivedMessages.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string>& WebSocketChat::getReceivedMessages() const
|
const std::vector<std::string>& WebSocketBroadcastChat::getReceivedMessages() const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
return _receivedMessages;
|
return _receivedMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketChat::appendMessage(const std::string& message)
|
void WebSocketBroadcastChat::appendMessage(const std::string& message)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
_receivedMessages.push_back(message);
|
_receivedMessages.push_back(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketChat::isReady() const
|
bool WebSocketBroadcastChat::isReady() const
|
||||||
{
|
{
|
||||||
return _webSocket.getReadyState() == ix::ReadyState::Open;
|
return _webSocket.getReadyState() == ix::ReadyState::Open;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketChat::stop()
|
void WebSocketBroadcastChat::stop()
|
||||||
{
|
{
|
||||||
_webSocket.stop();
|
_webSocket.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketChat::start()
|
void WebSocketBroadcastChat::start()
|
||||||
{
|
{
|
||||||
std::string url;
|
std::string url;
|
||||||
{
|
{
|
||||||
@ -156,7 +158,8 @@ namespace
|
|||||||
_webSocket.start();
|
_webSocket.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string, std::string> WebSocketChat::decodeMessage(const std::string& str)
|
std::pair<std::string, std::string> WebSocketBroadcastChat::decodeMessage(
|
||||||
|
const std::string& str)
|
||||||
{
|
{
|
||||||
std::string errMsg;
|
std::string errMsg;
|
||||||
MsgPack msg = MsgPack::parse(str, errMsg);
|
MsgPack msg = MsgPack::parse(str, errMsg);
|
||||||
@ -167,7 +170,7 @@ namespace
|
|||||||
return std::pair<std::string, std::string>(msg_user, msg_text);
|
return std::pair<std::string, std::string>(msg_user, msg_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WebSocketChat::encodeMessage(const std::string& text)
|
std::string WebSocketBroadcastChat::encodeMessage(const std::string& text)
|
||||||
{
|
{
|
||||||
std::map<MsgPack, MsgPack> obj;
|
std::map<MsgPack, MsgPack> obj;
|
||||||
obj["user"] = _user;
|
obj["user"] = _user;
|
||||||
@ -179,7 +182,7 @@ namespace
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketChat::sendMessage(const std::string& text)
|
void WebSocketBroadcastChat::sendMessage(const std::string& text)
|
||||||
{
|
{
|
||||||
_webSocket.sendBinary(encodeMessage(text));
|
_webSocket.sendBinary(encodeMessage(text));
|
||||||
}
|
}
|
||||||
@ -248,11 +251,11 @@ TEST_CASE("Websocket_broadcast_server", "[websocket_server]")
|
|||||||
REQUIRE(startServer(server, connectionId));
|
REQUIRE(startServer(server, connectionId));
|
||||||
|
|
||||||
std::string session = ix::generateSessionId();
|
std::string session = ix::generateSessionId();
|
||||||
std::vector<std::shared_ptr<WebSocketChat>> chatClients;
|
std::vector<std::shared_ptr<WebSocketBroadcastChat>> chatClients;
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
std::string user("user_" + std::to_string(i));
|
std::string user("user_" + std::to_string(i));
|
||||||
chatClients.push_back(std::make_shared<WebSocketChat>(user, session, port));
|
chatClients.push_back(std::make_shared<WebSocketBroadcastChat>(user, session, port));
|
||||||
chatClients[i]->start();
|
chatClients[i]->start();
|
||||||
ix::msleep(50);
|
ix::msleep(50);
|
||||||
}
|
}
|
||||||
|
80
ws/ws.cpp
80
ws/ws.cpp
@ -152,7 +152,7 @@ namespace
|
|||||||
idx = path.rfind('.');
|
idx = path.rfind('.');
|
||||||
if (idx != std::string::npos)
|
if (idx != std::string::npos)
|
||||||
{
|
{
|
||||||
std::string filename = path.substr(idx + 1);
|
std::string filename = path.substr(0, idx);
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1220,6 +1220,11 @@ namespace ix
|
|||||||
|
|
||||||
std::ofstream f;
|
std::ofstream f;
|
||||||
f.open(outputFilename);
|
f.open(outputFilename);
|
||||||
|
if (!f.is_open())
|
||||||
|
{
|
||||||
|
spdlog::error("Cannot open {} for writing", outputFilename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
f << decompressedBytes;
|
f << decompressedBytes;
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
@ -1268,45 +1273,56 @@ namespace ix
|
|||||||
std::condition_variable condition;
|
std::condition_variable condition;
|
||||||
|
|
||||||
std::atomic<bool> stop(false);
|
std::atomic<bool> stop(false);
|
||||||
|
std::chrono::time_point<std::chrono::high_resolution_clock> start;
|
||||||
|
|
||||||
// Setup a callback to be fired
|
// Setup a callback to be fired
|
||||||
// when a message or an event (open, close, ping, pong, error) is received
|
// when a message or an event (open, close, ping, pong, error) is received
|
||||||
webSocket.setOnMessageCallback([&receivedCountPerSecs, &target, &stop, &condition, &bench](
|
webSocket.setOnMessageCallback(
|
||||||
const ix::WebSocketMessagePtr& msg) {
|
[&receivedCountPerSecs, &target, &stop, &condition, &bench, &start](
|
||||||
if (msg->type == ix::WebSocketMessageType::Message)
|
const ix::WebSocketMessagePtr& msg) {
|
||||||
{
|
if (msg->type == ix::WebSocketMessageType::Message)
|
||||||
receivedCountPerSecs++;
|
|
||||||
|
|
||||||
target -= 1;
|
|
||||||
if (target == 0)
|
|
||||||
{
|
{
|
||||||
stop = true;
|
receivedCountPerSecs++;
|
||||||
condition.notify_one();
|
|
||||||
|
|
||||||
bench.report();
|
target -= 1;
|
||||||
|
if (target == 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
condition.notify_one();
|
||||||
|
|
||||||
|
bench.report();
|
||||||
|
|
||||||
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
auto milliseconds =
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
|
||||||
|
auto duration = milliseconds.count();
|
||||||
|
|
||||||
|
spdlog::info("AUTOROUTE IXWebSocket :: {} ms", duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (msg->type == ix::WebSocketMessageType::Open)
|
||||||
else if (msg->type == ix::WebSocketMessageType::Open)
|
|
||||||
{
|
|
||||||
bench.reset();
|
|
||||||
|
|
||||||
spdlog::info("ws_autoroute: connected");
|
|
||||||
spdlog::info("Uri: {}", msg->openInfo.uri);
|
|
||||||
spdlog::info("Headers:");
|
|
||||||
for (auto it : msg->openInfo.headers)
|
|
||||||
{
|
{
|
||||||
spdlog::info("{}: {}", it.first, it.second);
|
bench.reset();
|
||||||
|
|
||||||
|
spdlog::info("ws_autoroute: connected");
|
||||||
|
spdlog::info("Uri: {}", msg->openInfo.uri);
|
||||||
|
spdlog::info("Headers:");
|
||||||
|
for (auto it : msg->openInfo.headers)
|
||||||
|
{
|
||||||
|
spdlog::info("{}: {}", it.first, it.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
}
|
else if (msg->type == ix::WebSocketMessageType::Pong)
|
||||||
else if (msg->type == ix::WebSocketMessageType::Pong)
|
{
|
||||||
{
|
spdlog::info("Received pong {}", msg->str);
|
||||||
spdlog::info("Received pong {}", msg->str);
|
}
|
||||||
}
|
else if (msg->type == ix::WebSocketMessageType::Close)
|
||||||
else if (msg->type == ix::WebSocketMessageType::Close)
|
{
|
||||||
{
|
spdlog::info("ws_autoroute: connection closed");
|
||||||
spdlog::info("ws_autoroute: connection closed");
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
auto timer = [&receivedCountPerSecs, &stop] {
|
auto timer = [&receivedCountPerSecs, &stop] {
|
||||||
setThreadName("Timer");
|
setThreadName("Timer");
|
||||||
|
Reference in New Issue
Block a user