Skip to content

Commit fcde559

Browse files
committed
Change name back to websocket_proxy; fix shutdown issue; add example
1 parent 08aa6f1 commit fcde559

File tree

16 files changed

+801
-243
lines changed

16 files changed

+801
-243
lines changed

CMakeLists.txt

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
cmake_minimum_required(VERSION 3.15)
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
set(VCPKG_TARGET_TRIPLET x64-windows-static)
4+
5+
set(CMAKE_CXX_STANDARD 20)
26

37
file (STRINGS "version" BUILD_VERSION)
48

5-
project(alpaca_websocket_proxy
9+
project(websocket_proxy
610
VERSION ${BUILD_VERSION}
711
LANGUAGES CXX)
812

9-
set(CMAKE_CXX_STANDARD 20)
10-
1113
if (NOT CMAKE_BUILD_TYPE)
1214
set(CMAKE_BUILD_TYPE Release)
1315
endif()
@@ -20,56 +22,60 @@ if (CMAKE_BUILD_TYPE MATCHES Release)
2022
add_definitions(-DNDEBUG)
2123
endif()
2224

23-
set(VCPKG_TARGET_TRIPLET x64-windows-static)
24-
25-
set(RELEASE_DIR "${CMAKE_CURRENT_BINARY_DIR}/release")
26-
configure_file(src/version.h.in release/include/alpaca_websocket_proxy/version.h)
25+
set(Boost_USE_STATIC_LIBS ON)
26+
find_package(Boost REQUIRED COMPONENTS beast context)
2727

2828
set(OPENSSL_USE_STATIC_LIBS TRUE)
2929
set(OPENSSL_MSVC_STATIC_RT TRUE)
30-
31-
find_package(boost_beast REQUIRED CONFIG)
3230
find_package(OpenSSL REQUIRED)
31+
3332
find_package(spdlog REQUIRED CONFIG)
3433
add_definitions(-DSPDLOG_USE_STD_FORMAT -DSPDLOG_USE_STD_FORMAT_HO)
3534

3635
include(cmake/slick_queue.cmake)
3736

38-
set(HEADERS
39-
include/alpaca_websocket_proxy/type.h
40-
include/alpaca_websocket_proxy/alpaca_websocket_proxy_client.h
41-
)
37+
message(STATUS "OpenSSL: ${OPENSSL_INCLUDE_DIR}")
38+
message(STATUS "Beast: ${boost_beast_CONFIG}")
39+
message(STATUS "spdlog: ${spdlog_CONFIG}")
40+
41+
set(RELEASE_DIR "${CMAKE_CURRENT_BINARY_DIR}/dist")
42+
configure_file(src/version.h.in dist/include/websocket_proxy/version.h)
4243

4344
set(SOURCES
4445
src/main.cpp
45-
src/alpaca_websocket_proxy.cpp
46+
src/websocket_proxy.cpp
4647
)
4748

48-
add_executable(alpaca_websocket_proxy ${SOURCES})
49-
target_include_directories(alpaca_websocket_proxy PUBLIC include ${slick_queue_SOURCE_DIR}/include ${spdlog_SOURCE_DIR} ${RELEASE_DIR}/include)
50-
target_link_libraries(alpaca_websocket_proxy PRIVATE spdlog::spdlog_header_only Boost::asio Boost::beast OpenSSL::SSL OpenSSL::Crypto)
51-
target_precompile_headers(alpaca_websocket_proxy PRIVATE src/pch.hpp)
49+
add_executable(websocket_proxy ${SOURCES})
50+
target_include_directories(websocket_proxy PUBLIC include ${slick_queue_SOURCE_DIR}/include ${RELEASE_DIR}/include)
51+
target_link_libraries(websocket_proxy PRIVATE spdlog::spdlog_header_only Boost::asio Boost::beast Boost::context OpenSSL::SSL OpenSSL::Crypto)
52+
target_link_libraries(websocket_proxy PRIVATE ${VCPKG_ROOT})
5253

5354
if (MSVC)
55+
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
5456
add_definitions(-D_WIN32_WINNT=0x0A00)
5557
set(CMAKE_SUPPRESS_REGENERATION true) # supress zero_check
56-
set_target_properties(alpaca_websocket_proxy PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
57-
set_target_properties(alpaca_websocket_proxy PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin/Debug")
58-
set_target_properties(alpaca_websocket_proxy PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/Release")
59-
set_target_properties(alpaca_websocket_proxy PROPERTIES LINK_INCREMENTAL ON)
60-
target_compile_definitions(alpaca_websocket_proxy PUBLIC _UNICODE) # set CharacterSet to unicode
61-
target_compile_options(alpaca_websocket_proxy PRIVATE "/bigobj")
62-
set_target_properties(alpaca_websocket_proxy PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
58+
set_target_properties(websocket_proxy PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
59+
set_target_properties(websocket_proxy PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin/Debug")
60+
set_target_properties(websocket_proxy PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/Release")
61+
set_target_properties(websocket_proxy PROPERTIES LINK_INCREMENTAL ON)
62+
target_compile_definitions(websocket_proxy PUBLIC _UNICODE) # set CharacterSet to unicode
63+
target_compile_options(websocket_proxy PRIVATE "/bigobj")
64+
set_target_properties(websocket_proxy PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
65+
else()
66+
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
6367
endif()
6468

6569
if (CMAKE_BUILD_TYPE MATCHES Release)
66-
add_custom_command(TARGET alpaca_websocket_proxy
70+
add_custom_command(TARGET websocket_proxy
6771
POST_BUILD
6872
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/include ${RELEASE_DIR}/include
73+
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/_deps/slick_queue/include ${RELEASE_DIR}/include/websocket_proxy
6974
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/bin/Release ${RELEASE_DIR}/bin
70-
COMMAND ${CMAKE_COMMAND} -E tar "cfv" "alpca_websocket_proxy_${BUILD_VERSION}.zip" --format=zip "${RELEASE_DIR}/bin" "${RELEASE_DIR}/include"
75+
COMMAND ${CMAKE_COMMAND} -E tar "cfv" "websocket_proxy_${BUILD_VERSION}.zip" --format=zip "${RELEASE_DIR}/bin" "${RELEASE_DIR}/include"
7176
WORKING_DIRECTORY "${RELEASE_DIR}"
7277
COMMENT "Creating zip archive"
7378
)
7479
endif()
7580

81+
add_subdirectory(example EXLCUDE_FROM_ALL)

README.md

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,77 @@
1-
# AlpacaWebsocketProxy: Share a Single WebSocket Connection for Multiple Clients (C++)
2-
AlpacaWebSocketProxy provides a C++ WebSocket proxy framework that empowers you to share a single WebSocket connection among multiple clients, maximizing resource utilization and streamlining real-time data access.
3-
4-
## Built for Efficiency: Serving Multiple Clients with One Connection
5-
Designed initially for the [Alpaca.Market](https://alpaca.markets/), which offers data via both REST and WebSockets. However, Alpaca limits the number of concurrent WebSocket connections per account. AlpacaWebSocketProxy solves this by enabling multiple strategies under the same account to receive real-tine market data updates through a single, shared WebSocket connection.
6-
7-
## Components and Communication
8-
AlpacaWebSocketProxy consists of two components:
9-
1. Standalone proxy server executable: This executable acts as the central communication hub. It manages the connection to the WebSocket server and handles data forwarding between clients. It's launched upon the first client attempting a WebSocket connection, ensuring only one server instance runs simultaneously. Any subsequent server launch attempts automatically terminate, preventing resource conflicts. The server continues execution until all connected clients are closed.
10-
2. Header-only Proxy Client: This lightweight client library integrates into your individual applications. It manages communication with the proxy server and provides a familiar interface for sending and receiving data.
11-
12-
## Benefits of AlpacaWebSocketProxy
13-
* Efficient Resource Utilization: Share a single WebSocket connection, reducing overhead and improving resource management.
14-
* Real-Time Data Streamlining: Multiple trading strategies within an account gain access to crucial market updates concurrently.
15-
* Simplified Integration: The header-only client library enables effortless integration with your existing client applications.
16-
* Shared Memory Optimization: Communication between server and clients leverages shared memory ring buffers, ensuring high-performance data exchange.
1+
# WebsocketProxy: Share a Single WebSocket Connection for Multiple Clients (C++)
2+
WebsocketProxy is a C++ framework that allows multiple clients to share a single WebSocket connection, optimizing resource usage and enhancing real-time data access.
3+
4+
## Efficiently Serve Multiple Clients
5+
Originally designed for [Alpaca.Market](https://alpaca.markets/), which provides data through both REST and WebSockets. However, Alpaca only allows one WebSocket connection per account. WebsocketProxy enables multiple strategies under the same account to receive real-time market data updates via a single shared WebSocket connection. WebsocketProxy doesn't have any Alpaca API protocol. It passes through messages between clients and server, making it suitable for other WebSocket connections as well.
6+
7+
## Components
8+
WebsocketProxy comprises two main components:
9+
1. **Standalone Proxy Server**: This executable serves as the central communication hub, managing the WebSocket server connection and data forwarding between clients. It launches with the first client connection attempt, ensuring only one server instance runs at a time. Subsequent server launch attempts are automatically terminated to prevent conflicts. The server continues running until all clients disconnect.
10+
2. **Header-only Proxy Client**: This lightweight client library integrates seamlessly into your applications, managing communication with the proxy server and providing an interface for data transmission.
11+
12+
## Installation
13+
14+
To install WebsocketProxy, simply download the latest release from the [releases page](https://github.com/kzhdev/websocket_proxy/releases), unzip the package, and copy the `include` folder to your project directory.
15+
16+
Then, derive from the `WebsocketProxyCallback` class and implement the corresponding callback functions. For reference, check the Alpaca WebSocket client example in the [example](https://github.com/kzhdev/websocket_proxy/tree/main/example) directory.
17+
18+
19+
## Build From the Source Code
20+
21+
To build WebsocketProxy, follow these steps:
22+
23+
### Installing Dependencies
24+
25+
WebsocketProxy relies on several external libraries. You can install these dependencies using [vcpkg](https://github.com/microsoft/vcpkg). Follow these steps to install the required libraries:
26+
27+
1. **Install vcpkg**:
28+
```sh
29+
git clone https://github.com/microsoft/vcpkg.git
30+
cd vcpkg
31+
./bootstrap-vcpkg.sh
32+
```
33+
34+
2. **Install Required Libraries**:
35+
```sh
36+
./vcpkg install spdlog:x64-windows-static
37+
./vcpkg install boost-beast:x64-windows-static
38+
./vcpkg install openssl:x64-windows-static
39+
```
40+
41+
3. **Integrate vcpkg with CMake**:
42+
Add the following line to your CMake configuration to use vcpkg:
43+
```sh
44+
cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
45+
```
46+
47+
### Build WebsocketProxy
48+
49+
1. **Clone the Repository**:
50+
```sh
51+
git clone https://github.com/kzhdev/websocket_proxy.git
52+
cd websocket_proxy
53+
```
54+
55+
2. **Build the Proxy Server**:
56+
Ensure you have a C++ compiler and CMake installed. Then, run the following commands:
57+
```sh
58+
cmake -S . -B build
59+
cmake --build ./build --config Release -j 18
60+
```
61+
62+
3. **Include the Client Library**:
63+
Copy the include folder from the repository to your project:
64+
```sh
65+
cp -r include /path/to/your/project/include/
66+
```
67+
4. **Derive from the `WebsocketProxyCallback` class and implement the corresponding callback functions**
68+
69+
For reference, check the Alpaca WebSocket client example in the [example](https://github.com/kzhdev/websocket_proxy/tree/main/example) directory.
70+
71+
## Contributing
72+
73+
Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/kzhdev/websocket_proxy).
74+
75+
## License
76+
77+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

example/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
project(example_websocket_client LANGUAGES CXX)
2+
3+
include(FetchContent)
4+
FetchContent_Declare(json
5+
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
6+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
7+
FetchContent_MakeAvailable(json)
8+
9+
add_executable(example_websocket_client main.cpp)
10+
target_compile_definitions(example_websocket_client PUBLIC _UNICODE)
11+
target_include_directories(example_websocket_client PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include ${RapidJSON_SOURCE_DIR}/include ${slick_queue_SOURCE_DIR}/include)
12+
target_link_libraries(example_websocket_client PRIVATE nlohmann_json::nlohmann_json)
13+
14+

0 commit comments

Comments
 (0)