Skip to content

Commit 72c9cd2

Browse files
committed
Added HTTP client base that enables SM to make async HTTP requests and receive the responses as callbacks accessable by client behaviors
1 parent f9640e0 commit 72c9cd2

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#pragma once
2+
3+
#include <cpr/cpr.h> // Make sure this header is available in your include path
4+
#include <smacc/impl/smacc_state_impl.h>
5+
#include <smacc/smacc_client.h>
6+
7+
#include <boost/optional/optional_io.hpp>
8+
9+
namespace smacc {
10+
namespace client_bases {
11+
12+
class SmaccHttpClient : public smacc::ISmaccClient {
13+
public:
14+
boost::optional<std::string> serverName;
15+
boost::optional<int> timeout;
16+
17+
SmaccHttpClient() { initialized_ = false; }
18+
19+
SmaccHttpClient(const std::string &serverName, const int &timeout) {
20+
this->serverName = serverName;
21+
this->timeout = timeout;
22+
}
23+
24+
smacc::SmaccSignal<void(const cpr::Response &)> onResponseReceived_;
25+
26+
template <typename T>
27+
boost::signals2::connection onResponseReceived(
28+
void (T::*callback)(const cpr::Response &), T *object) {
29+
return this->getStateMachine()->createSignalConnection(onResponseReceived_,
30+
callback, object);
31+
}
32+
33+
template <typename TOrthogonal, typename TSourceObject>
34+
void onOrthogonalAllocation() {}
35+
36+
virtual void initialize() {
37+
if (!initialized_) {
38+
if (!timeout) timeout = 2000; // 2s timeout default
39+
if (!serverName) {
40+
ROS_ERROR("Server URL not set, skipping initialisation");
41+
} else {
42+
ROS_INFO_STREAM("[" << this->getName()
43+
<< "] Initialising HTTP client for " << serverName);
44+
initialized_ = true;
45+
}
46+
}
47+
}
48+
49+
// cpr::Header is an STL map-like object mapping string key-value pairs,
50+
// e.g. {"Content-Type", "application/json"}
51+
void makePostRequest(const std::string &path, const std::string &body,
52+
const cpr::Header &header) {
53+
if (!initialized_) {
54+
ROS_ERROR("%s: not initialized.", this->getName().c_str());
55+
return;
56+
}
57+
if (!serverName) {
58+
ROS_ERROR("Server URL not set.");
59+
return;
60+
}
61+
request_ = cpr::PostCallback(
62+
[this](const cpr::Response &response) {
63+
onResponseReceived_(response);
64+
},
65+
cpr::Url{serverName.get() + path}, cpr::Body{{body}},
66+
cpr::Header{header}, cpr::Timeout{timeout.get()});
67+
}
68+
69+
void makeGetRequest(const std::string &path, const std::string &body = "",
70+
const cpr::Header &header = {}) {
71+
if (!initialized_) {
72+
ROS_ERROR("%s: not initialized.", this->getName().c_str());
73+
return;
74+
}
75+
if (!serverName) {
76+
ROS_ERROR("Server URL not set.");
77+
return;
78+
}
79+
request_ = cpr::GetCallback(
80+
[this](const cpr::Response &response) {
81+
onResponseReceived_(response);
82+
},
83+
cpr::Url{serverName.get() + path}, cpr::Body{{body}},
84+
cpr::Header{header}, cpr::Timeout{timeout.get()});
85+
}
86+
87+
private:
88+
bool initialized_;
89+
std::future<void> request_;
90+
};
91+
} // namespace client_bases
92+
} // namespace smacc

0 commit comments

Comments
 (0)