Skip to content

FX_WebSocket.cpp Program Flow #1173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"files.associations": {
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"strstream": "cpp",
"bit": "cpp",
"bitset": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"coroutine": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"shared_mutex": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"variant": "cpp"
}
}
Binary file added FX_WebSocket
Binary file not shown.
109 changes: 109 additions & 0 deletions FX_WebSocket.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "/home/nadkalpur/Documents/websocketpp/websocketpp/asio_client.hpp" // Include the WebSocket++ ASIO client header
#include <websocketpp/client.hpp> // Include the WebSocket++ client header
#include <iostream> // Include the standard I/O library

// Define the WebSocket++ client type using the ASIO TLS client configuration
using client = websocketpp::client<websocketpp::config::asio_tls_client>;

// Define the shared pointer type for SSL context
using context_ptr = websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context>;

// Import placeholders for binding functions
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;

// Import the bind function for binding handlers
using websocketpp::lib::bind;

// Use the std::string_literals namespace for string literals
using namespace std::string_literals;

// Handler for when the WebSocket connection is opened
void on_open(websocketpp::connection_hdl hdl, client* c) {
std::cout << "WebSocket connection opened!" << std::endl;

websocketpp::lib::error_code ec; // Error code object
client::connection_ptr con = c->get_con_from_hdl(hdl, ec); // Get the connection pointer from the handle

if (ec) { // Check if there was an error
std::cout << "Failed to get connection pointer: " << ec.message() << std::endl;
return;
}

// Payload to send to the WebSocket server
std::string payload = "{\"userKey\":\"wsO10gpDdcV2gIBLBrnw\", \"symbol\":\"EURUSD,GBPUSD\"}";
c->send(con, payload, websocketpp::frame::opcode::text); // Send the payload
}

// Handler for when a message is received
void on_message(websocketpp::connection_hdl, client::message_ptr msg) {
std::cout << "Currency Pairs: " << msg->get_payload() << std::endl; // Print the received message
}

// Handler for when the WebSocket connection fails
void on_fail(websocketpp::connection_hdl hdl) {
std::cout << "WebSocket connection failed!" << std::endl;
}

// Handler for when the WebSocket connection is closed
void on_close(websocketpp::connection_hdl hdl) {
std::cout << "WebSocket connection closed!" << std::endl;
}

// Handler for initializing the TLS context
context_ptr on_tls_init(const char* hostname, websocketpp::connection_hdl) {
// Create a shared pointer for the SSL context
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(
boost::asio::ssl::context::tlsv12); // Use TLS v1.2

try {
using boost::asio::ssl::context; // Simplify the context namespace usage
// Set SSL context options
ctx->set_options(context::default_workarounds |
context::no_sslv2 |
context::no_sslv3 |
context::single_dh_use);
} catch (std::exception& e) { // Catch any exceptions
std::cout << "TLS Initialization Error: " << e.what() << std::endl;
}

return ctx; // Return the SSL context
}

// Main function
int main(int argc, char* argv[]) {
client c; // Create a WebSocket++ client object

// Define the hostname and URI for the WebSocket server
std::string hostname = "marketdata.tradermade.com/feedadv";
std::string uri = "wss://" + hostname;

try {
// Set logging options for the client
c.set_access_channels(websocketpp::log::alevel::all); // Enable all access logs
c.clear_access_channels(websocketpp::log::alevel::frame_payload); // Disable frame payload logs
c.set_error_channels(websocketpp::log::elevel::all); // Enable all error logs

c.init_asio(); // Initialize the ASIO transport

// Set the handlers for various WebSocket events
c.set_message_handler(&on_message); // Set the message handler
c.set_tls_init_handler(bind(&on_tls_init, hostname.c_str(), ::_1)); // Set the TLS initialization handler
c.set_open_handler(bind(&on_open, ::_1, &c)); // Set the open handler
c.set_fail_handler(bind(&on_fail, ::_1)); // Set the fail handler
c.set_close_handler(bind(&on_close, ::_1)); // Set the close handler

websocketpp::lib::error_code ec; // Error code object
client::connection_ptr con = c.get_connection(uri, ec); // Create a connection to the server

if (ec) { // Check if there was an error
std::cout << "Could not create connection because: " << ec.message();
return 0;
}

c.connect(con); // Connect to the server
c.run(); // Start the ASIO event loop
} catch (websocketpp::exception const& e) { // Catch any WebSocket++ exceptions
std::cout << "WebSocket Exception: " << e.what() << std::endl;
}
}
41 changes: 41 additions & 0 deletions try_block_notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
This code snippet is part of a WebSocket client implementation using the WebSocket++ library. It demonstrates the setup and initialization
of a WebSocket client, including logging configuration, event handlers, and connection establishment.

First, the logging options for the WebSocket client (`c`) are configured. The `set_access_channels` method enables all access-level logs,
providing detailed information about the client's operations. However, the `clear_access_channels` method is used to disable frame payload logs,
which can be verbose and unnecessary in many cases. Additionally, the `set_error_channels` method enables all error-level logs,
ensuring that any issues encountered by the client are logged for debugging purposes.

Next, the `init_asio` method initializes the ASIO transport layer, which is required for WebSocket++ to handle network communication.
This step is essential for enabling the client to send and receive WebSocket messages over the network.

The code then sets up various event handlers to manage WebSocket events. The `set_message_handler` method assigns
a handler function (`on_message`) to process incoming messages. The `set_tls_init_handler` method binds
the `on_tls_init` function to handle TLS initialization, passing the hostname and a placeholder argument (`::_1`).
Similarly, the `set_open_handler`, `set_fail_handler`, and `set_close_handler` methods bind their
respective functions (`on_open`, `on_fail`, and `on_close`) to handle connection opening, failure, and closure events.

An error code object (`websocketpp::lib::error_code ec`) is created to capture any errors that occur during the connection process.
The `get_connection` method is then called to establish a connection to the specified server URI (`uri`). If an error occurs
during this process, it is logged using `ec.message()`, and the function returns early with a value of `0`.

This code is a foundational part of a WebSocket client, setting up the necessary components and handlers to
manage WebSocket communication effectively. It ensures robust error handling and logging, making it easier
to debug and maintain the client.

/ Import placeholders for binding functions
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;


This code snippet imports placeholders `_1` and `_2` from the `websocketpp::lib::placeholders` namespace. These placeholders are used in conjunction
with the `bind` function to create callable objects that can defer the invocation of a function until later, while also allowing partial application
of arguments.

In the context of the WebSocket++ library, these placeholders are commonly used to bind event handler functions to specific WebSocket events,
such as when a connection is opened, closed, or fails. The placeholders `_1` and `_2` act as stand-ins for arguments that will be provided at
runtime when the event occurs. For example, `_1` might represent the connection handle, while `_2` could represent additional event-specific data.

By importing these placeholders, the code avoids the need to fully qualify them (e.g., `websocketpp::lib::placeholders::_1`) every time they are used,
improving readability and reducing verbosity. This is particularly useful in event-driven programming, where binding functions with placeholders
is a common pattern.
16 changes: 16 additions & 0 deletions websocketpp/.vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/home/nadkalpur/Documents/websocketpp"
],
"defines": [],
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
77 changes: 77 additions & 0 deletions websocketpp/asio_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP
#define WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP

#include <websocketpp/config/core_client.hpp>
#include <websocketpp/transport/asio/endpoint.hpp>
#include <websocketpp/transport/asio/security/tls.hpp>

// Pull in non-tls config
#include <websocketpp/config/asio_no_tls_client.hpp>

// Define TLS config
namespace websocketpp {
namespace config {

/// Client config with asio transport and TLS enabled
struct asio_tls_client : public core_client {
typedef asio_tls_client type;
typedef core_client base;

typedef base::concurrency_type concurrency_type;

typedef base::request_type request_type;
typedef base::response_type response_type;

typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;

typedef base::alog_type alog_type;
typedef base::elog_type elog_type;

typedef base::rng_type rng_type;

struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
};

typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
};

} // namespace config
} // namespace websocketpp

#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP