FastLED 3.9.15
Loading...
Searching...
No Matches

◆ setup()

void setup ( )

Definition at line 100 of file RpcBidirectional.ino.

100 {
101 Serial.begin(115200);
102 while (!Serial && millis() < 3000) {
103 // Wait for serial or timeout
104 }
105
106 Serial.println("\n=== HTTP RPC Bidirectional Example ===\n");
107 Serial.println("This example demonstrates server + client in one process:");
108 Serial.println(" - Server listens on port 8080");
109 Serial.println(" - Client connects to localhost:8080");
110 Serial.println(" - All three RPC modes demonstrated");
111 Serial.println();
112
113 // Initialize LEDs
114 FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
115 FastLED.setBrightness(50);
117 FastLED.show();
118
119 // ========== SERVER SETUP ==========
120 Serial.println("Starting HTTP server on port 8080...");
121
123 serverTransport->setHeartbeatInterval(30000);
124 serverTransport->setTimeout(60000);
125
126 // Connection callbacks
127 serverTransport->setOnConnect([]() {
128 Serial.println("[SERVER] Client connected!");
129 leds[0] = CRGB::Green;
130 FastLED.show();
131 });
132
133 serverTransport->setOnDisconnect([]() {
134 Serial.println("[SERVER] Client disconnected!");
135 leds[0] = CRGB::Red;
136 FastLED.show();
137 });
138
139 // Create server Remote
141 []() { return serverTransport->readRequest(); },
142 [](const fl::json& response) { serverTransport->writeResponse(response); }
143 );
144
145 // ========== BIND SERVER METHODS ==========
146
147 // SYNC mode: add(a, b)
148 serverRemote->bind("add", [](const fl::json& params) -> fl::json {
149 int a = 0, b = 0;
150 if (params.is_array() && params.size() >= 2) {
151 auto aOpt = params[0].as_int();
152 auto bOpt = params[1].as_int();
153 if (aOpt && bOpt) {
154 a = *aOpt;
155 b = *bOpt;
156 }
157 }
158 int result = a + b;
159 fl::printf("[SERVER] add(%d, %d) = %d\n", a, b, result);
160 return fl::json(result);
161 });
162
163 // ASYNC mode: longTask(duration)
164 serverRemote->bindAsync("longTask", [](fl::ResponseSend& send, const fl::json& params) {
165 // Send ACK
167 ack.set("ack", true);
168 send.send(ack);
169
170 // Extract duration
171 int duration = 1000;
172 if (params.is_array() && params.size() > 0) {
173 auto durationOpt = params[0].as_int();
174 if (durationOpt) {
175 duration = *durationOpt;
176 }
177 }
178
179 fl::printf("[SERVER] longTask(%d) - ACK sent\n", duration);
180
181 // Simulate work
182 uint32_t startTime = millis();
183 while (millis() - startTime < static_cast<uint32_t>(duration)) {
184 delay(100);
185 }
186
187 // Send result
189 result.set("value", 42);
190 result.set("duration", duration);
191 send.send(result);
192
193 fl::printf("[SERVER] longTask(%d) - DONE\n", duration);
195
196 // ASYNC_STREAM mode: streamData(count)
197 serverRemote->bindAsync("streamData", [](fl::ResponseSend& send, const fl::json& params) {
198 // Send ACK
200 ack.set("ack", true);
201 send.send(ack);
202
203 // Extract count
204 int count = 5;
205 if (params.is_array() && params.size() > 0) {
206 auto countOpt = params[0].as_int();
207 if (countOpt) {
208 count = *countOpt;
209 }
210 }
211
212 fl::printf("[SERVER] streamData(%d) - ACK sent\n", count);
213
214 // Send updates
215 for (int i = 0; i < count; i++) {
216 fl::json update = fl::json::object();
217 update.set("update", i);
218 send.sendUpdate(update);
219 fl::printf("[SERVER] streamData - update %d/%d\n", i + 1, count);
220 delay(200);
221 }
222
223 // Send final
224 fl::json final = fl::json::object();
225 final.set("value", count);
226 send.sendFinal(final);
227
228 fl::printf("[SERVER] streamData(%d) - DONE\n", count);
230
231 // Start server
232 if (!serverTransport->connect()) {
233 Serial.println("ERROR: Failed to start server!");
234 return;
235 }
236 Serial.println("✓ Server started successfully");
237 fl::u16 actualPort = serverTransport->port();
238 Serial.print(" Listening on port: ");
239 Serial.println(actualPort);
240 Serial.println();
241
242 // Start server in background thread so client can connect without deadlock
243 serverRunning.store(true);
244 serverThread = std::thread(serverThreadFunc);
245
246 // Register cleanup listener now — must happen after thread starts so the
247 // thread is always joined during onExit(), even if setup() returns early.
248 // Without this, std::thread destructor calls std::terminate() on a joinable thread.
250
251 // ========== CLIENT SETUP ==========
252 delay(500); // Give server time to start and begin accepting connections
253
254 Serial.println("Connecting client to server...");
255
257 clientTransport->setHeartbeatInterval(30000);
258 clientTransport->setTimeout(60000);
259
260 // Connection callbacks
261 clientTransport->setOnConnect([]() {
262 Serial.println("[CLIENT] Connected to server!");
263 leds[9] = CRGB::Blue;
264 FastLED.show();
265 });
266
267 clientTransport->setOnDisconnect([]() {
268 Serial.println("[CLIENT] Disconnected from server!");
269 leds[9] = CRGB::Red;
270 FastLED.show();
271 waitingForResponse = false;
272 });
273
274 // Create client Remote
276 []() { return clientTransport->readRequest(); },
277 [](const fl::json& response) { clientTransport->writeResponse(response); }
278 );
279
280 // Connect to server
281 if (!clientTransport->connect()) {
282 Serial.println("ERROR: Failed to connect to server!");
283 return;
284 }
285
286 Serial.println("✓ Client connected successfully\n");
287 Serial.println("Starting test sequence...\n");
288}
#define NUM_LEDS
fl::CRGB leds[NUM_LEDS]
#define DATA_PIN
Definition ClientReal.h:82
#define SERVER_PORT
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
static ServerCleanup serverCleanup
fl::unique_ptr< fl::Remote > clientRemote
std::atomic< bool > serverRunning(false)
fl::unique_ptr< fl::net::http::HttpStreamClient > clientTransport
void serverThreadFunc()
fl::unique_ptr< fl::net::http::HttpStreamServer > serverTransport
std::thread serverThread
bool waitingForResponse
fl::unique_ptr< fl::Remote > serverRemote
static void addListener(Listener *listener, int priority=0) FL_NOEXCEPT
void send(const fl::json &result)
Send a single response (for ASYNC mode)
void sendFinal(const fl::json &result)
Send final response and mark stream as complete (for ASYNC_STREAM mode)
void sendUpdate(const fl::json &update)
Send intermediate streaming update (for ASYNC_STREAM mode)
Helper class for sending responses in async/streaming RPC methods.
fl::optional< i64 > as_int() const FL_NOEXCEPT
Definition json.h:255
bool is_array() const FL_NOEXCEPT
Definition json.h:246
size_t size() const FL_NOEXCEPT
Definition json.h:633
void set(const fl::string &key, const json &value) FL_NOEXCEPT
Definition json.h:701
static json object() FL_NOEXCEPT
Definition json.h:692
void fill_solid(CRGB *targetArray, int numToFill, const CRGB &color) FL_NOEXCEPT
Fill a range of LEDs with a solid color.
Definition fill.cpp.hpp:9
constexpr EOrder GRB
Definition eorder.h:19
fl::u32 uint32_t
Definition s16x16x4.h:219
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
void printf(const char *format, const Args &... args) FL_NOEXCEPT
Printf-like formatting function that prints directly to the platform output.
Definition stdio.h:635
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NOEXCEPT
Definition unique_ptr.h:261
void delay(u32 ms, bool run_async=true) FL_NOEXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
Definition delay.h:98
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
@ Green
<div style='background:#008000;width:4em;height:4em;'></div>
Definition crgb.h:558
@ Red
<div style='background:#FF0000;width:4em;height:4em;'></div>
Definition crgb.h:622
@ Blue
<div style='background:#0000FF;width:4em;height:4em;'></div>
Definition crgb.h:512
@ Black
<div style='background:#000000;width:4em;height:4em;'></div>
Definition crgb.h:510
#define Serial
Definition serial.h:304

References fl::EngineEvents::addListener(), fl::json::as_int(), fl::ASYNC, fl::ASYNC_STREAM, fl::CRGB::Black, fl::CRGB::Blue, clientRemote, clientTransport, DATA_PIN, FastLED, fill_solid(), GRB, fl::CRGB::Green, fl::json::is_array(), leds, fl::make_unique(), NUM_LEDS, fl::json::object(), fl::printf(), fl::CRGB::Red, fl::ResponseSend::send(), fl::ResponseSend::sendFinal(), fl::ResponseSend::sendUpdate(), Serial, SERVER_PORT, serverCleanup, serverRemote, serverRunning(), serverThread, serverThreadFunc(), serverTransport, fl::json::set(), fl::json::size(), and waitingForResponse.

+ Here is the call graph for this function: