Skip to content

Commit ba1fe0f

Browse files
authored
Merge pull request #8 from chandleg/stage
Stage
2 parents 93fcc73 + 5114ab4 commit ba1fe0f

File tree

16 files changed

+792
-178
lines changed

16 files changed

+792
-178
lines changed

.github/workflows/cpp-ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ jobs:
1313

1414
steps:
1515
- uses: actions/checkout@v3
16+
- name: Install Boost
17+
run: sudo apt-get install libboost-all-dev
1618
- name: Install dependencies
1719
run: sudo apt-get update && sudo apt-get install -y build-essential cmake
1820
- name: Configure CMake

.vscode/settings.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@
9393
"span": "cpp",
9494
"stop_token": "cpp",
9595
"cfenv": "cpp",
96-
"typeindex": "cpp"
97-
}
96+
"typeindex": "cpp",
97+
"forward_list": "cpp",
98+
"unordered_set": "cpp",
99+
"csetjmp": "cpp",
100+
"barrier": "cpp",
101+
"slist": "cpp",
102+
"latch": "cpp",
103+
"ranges": "cpp",
104+
"shared_mutex": "cpp",
105+
"syncstream": "cpp",
106+
"valarray": "cpp"
107+
},
108+
"cmake.configureOnOpen": true
98109
}

API.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# API Manual
2+
3+
## Installation
4+
5+
The library requires the Boost Beast and Jsoncpp libraries to handle WebSocket communications and JSON data manipulation respectively. Install these dependencies using CMake if they are not already present on your system.
6+
7+
### Required Libraries
8+
- **Boost Beast** (version >= 1.76.0): Used for WebSocket implementation. Available at [boost.org](https://www.boost.org/).
9+
- **Jsoncpp**: Used for JSON parsing and serialization. Known for its performance and ease of use in C++ environments.
10+
11+
## Examples
12+
Two simple examples are provided demonstrating the Library in a simple raw C and a C++ classed implementation. Compile the examples using:
13+
```bash
14+
- mkdir build && cd build
15+
- cmake ..
16+
- make
17+
- ./example_client_simple or ./example_client_classed
18+
```
19+
20+
## Classes
21+
### Connection
22+
The `Connection` class manages WebSocket connections using Boost Beast. It handles asynchronous read, write, and connection management activities necessary for real-time communication.
23+
24+
#### Constructor
25+
- `Connection(net::io_context& ioc)`: Initializes a new connection with a given I/O context. This context is used to handle all I/O operations for the WebSocket.
26+
27+
#### Methods
28+
- `std::thread launch_socket(const char *host, const char *port)`: Starts the WebSocket connection on a separate thread.
29+
- `void stop()`: Stops the WebSocket connection and cleans up resources.
30+
- `void subscribe(std::string channel, socketCallback callback)`: Subscribes to a specific channel with a callback to handle incoming messages.
31+
- `void unsubscribe(std::string channel)`: Unsubscribes from a specific channel.
32+
- `void publish(std::string channel, std::string data)`: Publishes data to a specific channel.
33+
- `void message_processing()`: Handles the internal message processing in its thread.
34+
35+
#### Callbacks
36+
- `socketCallback`: A function type that handles incoming messages. Takes an event as `std::string` and data as `Json::Value`.
37+
38+
#### Members
39+
- `websocket::stream<beast::tcp_stream> ws_`: WebSocket stream for the connection.
40+
- `beast::flat_buffer buffer_`: Buffer used for reading WebSocket messages.
41+
42+
### SocketClusterClient
43+
44+
The `SocketClusterClient` class manages multiple WebSocket connections and provides methods to create and retrieve these connections.
45+
46+
#### Constructor
47+
- `SocketClusterClient()`: Initializes a new client capable of handling WebSocket connections.
48+
49+
#### Methods
50+
- `std::shared_ptr<Connection> createConnection(const char *url, const char *port)`: Creates and returns a new connection to the specified URL and port.
51+
- `std::list<std::shared_ptr<Connection>>& getConnections()`: Returns a list of all active connections.
52+
53+
#### Members
54+
- `std::list<std::shared_ptr<Connection>> m_connections`: List storing all managed connections.
55+
56+
57+
## Errors & Exceptions
58+
- `1000 - Normal Closure` : Connection closed successfully.
59+
- `1001 - Going Away` : Server or client is shutting down.
60+
- `1002 - Protocol Error` : Protocol violation detected.
61+
- `1003 - Unsupported Data` : The endpoint received data of a type it cannot accept.
62+
- `1006 - Abnormal Closure` : Connection closed abnormally without a status code.
63+
64+
65+
## Example Usage of SocketClusterClient Library
66+
67+
This example demonstrates how to use the `SocketClusterClient` and `Connection` classes to connect to a WebSocket server, subscribe to a channel, and handle incoming messages.
68+
69+
```cpp
70+
#include <iostream>
71+
#include "SocketClusterClient.h"
72+
73+
// Define a callback function to handle messages received on the WebSocket
74+
void handleMessage(std::string event, Json::Value data) {
75+
std::cout << "Event: " << event << "\nMessage received: " << data.toStyledString() << std::endl;
76+
}
77+
78+
int main() {
79+
// Create a client instance
80+
SocketClusterClient client;
81+
82+
// Create a new WebSocket connection to the desired host and port
83+
auto connection = client.createConnection("ws://example.com", "80");
84+
85+
// Subscribe to a channel with the defined callback
86+
connection->subscribe("exampleChannel", handleMessage);
87+
88+
// Publish to a channel
89+
connection->publish("exampleChannel", "Hello World!");
90+
91+
return 0;
92+
}

CMakeLists.txt

Lines changed: 22 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
cmake_minimum_required(VERSION 3.10) # Example minimum version
22
set(CMAKE_CXX_STANDARD 17)
33

4-
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -coverage")
5-
# set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -coverage")
6-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -O0")
7-
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -O0")
8-
94
project(SocketClusterClientCPP)
105

116
include(FetchContent)
@@ -18,55 +13,34 @@ FetchContent_Declare(JsonCpp
1813
FetchContent_MakeAvailable(JsonCpp)
1914
# === ===
2015

21-
# Fetch WebSocket++
22-
FetchContent_Declare(
23-
websocketpp
24-
GIT_REPOSITORY https://github.com/zaphoyd/websocketpp.git
25-
GIT_TAG master # It's better to use a specific commit or tag for reproducibility
26-
)
27-
28-
# Make WebSocket++ available for #include
29-
FetchContent_GetProperties(websocketpp)
30-
if(NOT websocketpp_POPULATED)
31-
FetchContent_Populate(websocketpp)
32-
include_directories(${websocketpp_SOURCE_DIR})
33-
endif()
34-
35-
# Fetch Asio (standalone version, without Boost)
16+
# set(BOOST_INCLUDE_LIBRARIES thread filesystem system program_options)
17+
set(BOOST_ENABLE_CMAKE ON)
18+
include(FetchContent)
3619
FetchContent_Declare(
37-
asio
38-
GIT_REPOSITORY https://github.com/chriskohlhoff/asio.git
39-
GIT_TAG asio-1-18-1 # Use a specific tag or commit to ensure reproducibility
20+
Boost
21+
GIT_REPOSITORY https://github.com/boostorg/boost.git
22+
GIT_TAG boost-1.74.0
23+
GIT_SHALLOW TRUE
4024
)
25+
FetchContent_MakeAvailable(Boost)
4126

42-
# Make Asio available for #include
43-
FetchContent_GetProperties(asio)
44-
if(NOT asio_POPULATED)
45-
FetchContent_Populate(asio)
46-
include_directories(${asio_SOURCE_DIR}/asio/include)
47-
add_definitions(-DASIO_STANDALONE)
48-
endif()
27+
find_package(Boost 1.74.0 REQUIRED)
4928

50-
# Build Library
5129
# Find source files
5230
file(GLOB_RECURSE LIBRARY_SOURCES src/*.cpp)
53-
54-
# Create the library
5531
add_library(SocketClusterClientCPP SHARED ${LIBRARY_SOURCES})
56-
57-
# Link against json-c
58-
target_link_libraries(SocketClusterClientCPP PRIVATE jsoncpp_static)
32+
target_link_libraries(SocketClusterClientCPP PUBLIC jsoncpp_lib)
5933

6034
# Update include directories to find json-c headers
6135
target_include_directories(SocketClusterClientCPP PUBLIC
6236
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
6337
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
64-
$<BUILD_INTERFACE:${JsonCpp_SOURCE_DIR}/_deps/jsoncpp-src/include>
65-
$<BUILD_INTERFACE:${websocketpp_SOURCE_DIR}/include>
66-
$<BUILD_INTERFACE:${asio_SOURCE_DIR}/include>
6738
$<BUILD_INTERFACE:${jsoncpp_SOURCE_DIR}/include>
39+
$<BUILD_INTERFACE:${websocketpp_SOURCE_DIR}/include>
6840
)
6941

42+
target_include_directories(SocketClusterClientCPP PUBLIC "${Boost_INCLUDE_DIRS}")
43+
7044
# Install targets and headers
7145
install(TARGETS SocketClusterClientCPP
7246
ARCHIVE DESTINATION lib
@@ -76,16 +50,22 @@ install(TARGETS SocketClusterClientCPP
7650
install(DIRECTORY src/
7751
DESTINATION include)
7852

53+
add_executable(simple_example test/examples/client_classed.cpp)
54+
target_link_libraries(simple_example PUBLIC SocketClusterClientCPP)
55+
56+
7957
# Coverage
80-
option(BUILD_TESTING "Builds only the test executable." ON)
81-
option(CODE_COVERAGE "Collect coverage from test library" ON)
58+
option(BUILD_TESTING "Builds only the test executable." OFF)
59+
option(CODE_COVERAGE "Collect coverage from test library" OFF)
8260

8361
if(BUILD_TESTING)
8462
enable_testing()
8563
add_subdirectory(test)
8664
add_test(NAME project_tests COMMAND ./bin/tests)
8765

8866
if(CODE_COVERAGE AND CMAKE_BUILD_TYPE MATCHES Debug)
67+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -O0")
68+
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -O0")
8969
# Set the coverage report output directory
9070
set(COVERAGE_DIR ${CMAKE_BINARY_DIR}/coverage)
9171

@@ -120,52 +100,11 @@ if(BUILD_TESTING)
120100

121101

122102
endif()
123-
124-
125-
# if(CODE_COVERAGE)
126-
# set(CODE_COVERAGE_VERBOSE TRUE)
127-
# include(CodeCoverage.cmake)
128-
# # append_coverage_compiler_flags()
129-
# append_coverage_compiler_flags_to_target(SocketClusterClientCPP)
130-
# # set(COVERAGE_EXCLUDES "src/*")
131-
# setup_target_for_coverage_lcov(
132-
# NAME coverage
133-
# EXECUTABLE ./bin/tests
134-
# # BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src/"
135-
# # EXCLUDE "*.cpp"
136-
# )
137-
138-
# # setup_target_for_coverage_lcov(
139-
# # NAME coverage
140-
# # EXECUTABLE ./bin/tests
141-
# # EXCLUDE "${PROJECT_SOURCE_DIR}/_deps/*"
142-
# # "${PROJECT_BINARY_DIR}/*"
143-
# # "${PROJECT_SOURCE_DIR}/test/*"
144-
# # )
145-
# endif()
146103
endif()
147104

148105

149106

150107

151108

152-
# # === websocket++ ===
153-
# FetchContent_Declare(websocketpp
154-
# GIT_REPOSITORY https://github.com/zaphoyd/websocketpp.git
155-
# GIT_TAG 0.8.2
156-
# )
157-
# FetchContent_GetProperties(websocketpp)
158-
# if(NOT websocketpp_POPULATED)
159-
# FetchContent_Populate(websocketpp)
160-
# add_subdirectory(${websocketpp_SOURCE_DIR} ${websocketpp_BINARY_DIR} EXCLUDE_FROM_ALL)
161-
# endif()
162-
# add_library(Websockets INTERFACE)
163-
# # === ===
164109

165-
# # === boost++ ===
166-
# FetchContent_Declare(
167-
# Boost
168-
# GIT_REPOSITORY https://github.com/boostorg/boost.git
169-
# GIT_TAG boost-1.80.0 # Replace with your desired version
170-
# )
171-
# FetchContent_MakeAvailable(Boost)
110+

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,30 @@
1-
# socketcluster-client-cpp
1+
# Socket Cluster C++ Client
2+
3+
This repository hosts a [SocketCluster](https://socketcluster.io/) C++ Client designed to facilitate communication between C++ applications and SocketCluster servers. This client supports real-time, scalable, bi-directional communication, making it ideal for applications requiring high performance and efficient data exchange.
4+
S
5+
This client is developed using the [Boost Beast](https://github.com/boostorg/beast) and [jsoncpp](https://github.com/open-source-parsers/jsoncpp) libraries in C++.
6+
7+
## Features
8+
9+
- **Real-Time Communication**: Enables real-time connectivity with SocketCluster servers.
10+
- **Bi-Directional Communication**: Supports both sending and receiving messages efficiently.
11+
- **Scalability**: Designed to handle high-load scenarios, making it suitable for large-scale deployments.
12+
- **WebSocket Support**: Utilizes WebSockets for low-latency communication.
13+
14+
15+
## Getting Starting
16+
A detailed list of the libraries API can be found [here](API.md).
17+
18+
## Security / SSL
19+
#### Tokens
20+
To address the threat of unauthenticated connections, we will utilize SocketCluster's built-in JWT-based authentication mechanism. Each JWT is uniquely signed using a server-specific authKey, ensuring secure and verified connections right from the initial handshake. Follow the guide [here](https://socketcluster.io/docs/authentication/) to enable JWTs with SocketCluster.
21+
#### WSS
22+
To allow development and production runs a flag can be set to enable SSL assuming the SocketCluster server has been configured to accept SSL connections. To best achieve this a flag can be set in the client to put the data transfer into the secure mode.
23+
```cpp
24+
#define SOCKETCLUSTER_SLL 1
25+
```
26+
27+
## Performance
28+
The maximum output and input rates have not been tested yet. This document will be updated with statistics after tests have been run. **Both example programs have been profiled and show no memory leaks.**
29+
30+
The SocketCluster server has been thoroughly tested in an [academic paper](https://arxiv.org/pdf/1409.3367.pdf). This client library aims to match the results listed.

0 commit comments

Comments
 (0)