mirror of
https://github.com/eclipse-paho/paho.mqtt.cpp.git
synced 2025-09-15 12:58:39 +08:00
Added ^C handling to some examples for clean exits.
This commit is contained in:
parent
33d219a2a3
commit
0bf6394fb3
@ -27,6 +27,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
- The `properties` list implements a const iterator
|
||||
- Added a `to_string()` and `operator<<()` for reason codes.
|
||||
- Cleaned up and fixed a number of example apps.
|
||||
- Most apps no except server URI from the command line
|
||||
- 'data_publish' example uses C++17 std::filesystem for creating a file-based encrypted persistence for messages.
|
||||
- Reorganized the source repository
|
||||
- Completely reformat the sources and added a .clang-format file (a project master and a slightly-different one for headers).
|
||||
- Added GitHub CI Action, removing legacy Travis and Appveyor files
|
||||
|
||||
@ -49,6 +49,8 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread> // For sleep
|
||||
#include <atomic>
|
||||
#include <csignal>
|
||||
|
||||
#include "mqtt/async_client.h"
|
||||
|
||||
@ -69,6 +71,14 @@ const int DELTA_MS = 100;
|
||||
// How many to buffer while off-line
|
||||
const int MAX_BUFFERED_MESSAGES = 1200;
|
||||
|
||||
// Atomic flag to tell the main loop to exit.
|
||||
atomic<bool> quit{false};
|
||||
|
||||
// Handler for ^C (SIGINT)
|
||||
void ctrlc_handler(int) {
|
||||
quit = true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Gets the current time as the number of milliseconds since the epoch:
|
||||
// like a time_t with ms resolution.
|
||||
@ -130,14 +140,17 @@ int main(int argc, char* argv[])
|
||||
auto top = mqtt::topic(cli, "data/time", QOS);
|
||||
cout << "Publishing data..." << endl;
|
||||
|
||||
// Install a ^C handler for user to signal when to exit
|
||||
signal(SIGINT, ctrlc_handler);
|
||||
|
||||
// Sync clock to start of delta period
|
||||
while (timestamp() % DELTA_MS != 0)
|
||||
;
|
||||
|
||||
uint64_t t = timestamp(), tlast = t, tstart = t;
|
||||
|
||||
top.publish(to_string(t));
|
||||
|
||||
while (true) {
|
||||
while (!quit) {
|
||||
this_thread::sleep_for(SAMPLE_PERIOD);
|
||||
|
||||
t = timestamp();
|
||||
|
||||
@ -52,6 +52,9 @@
|
||||
#include <thread>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <csignal>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "mqtt/async_client.h"
|
||||
|
||||
@ -77,6 +80,20 @@ const fs::path PERSIST_DIR{"persist"};
|
||||
// A key for encoding the persistence data
|
||||
const string PERSIST_KEY{"elephant"};
|
||||
|
||||
// Condition variable & flag to tell the main loop to exit.
|
||||
std::condition_variable cv;
|
||||
std::mutex mtx;
|
||||
bool quit{false};
|
||||
|
||||
// Handler for ^C (SIGINT)
|
||||
void ctrlc_handler(int) {
|
||||
{
|
||||
lock_guard<mutex> lk(mtx);
|
||||
quit = true;
|
||||
}
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Example of user-based file persistence with a simple XOR encoding scheme.
|
||||
@ -108,7 +125,7 @@ class encoded_file_persistence : virtual public mqtt::iclient_persistence
|
||||
}
|
||||
|
||||
// Gets the persistence file name for the supplied key.
|
||||
fs::path path_name(const string& key) const { return dir_ /key; }
|
||||
fs::path path_name(const string& key) const { return dir_ / key; }
|
||||
|
||||
public:
|
||||
// Create the persistence object with the specified encoding key
|
||||
@ -138,7 +155,10 @@ public:
|
||||
|
||||
// Close the persistent store that was previously opened.
|
||||
// Remove the persistence directory, if it's empty.
|
||||
void close() override { fs::remove(dir_); }
|
||||
void close() override {
|
||||
fs::remove(dir_);
|
||||
fs::remove(dir_.parent_path());
|
||||
}
|
||||
|
||||
// Clears persistence, so that it no longer contains any persisted data.
|
||||
// Just remove all the files from the persistence directory.
|
||||
@ -271,12 +291,18 @@ int main(int argc, char* argv[])
|
||||
char tmbuf[32];
|
||||
unsigned nsample = 0;
|
||||
|
||||
// The time at which to reads the next sample, starting now
|
||||
auto tm = steady_clock::now();
|
||||
// Install a ^C handler for user to signal when to exit
|
||||
signal(SIGINT, ctrlc_handler);
|
||||
|
||||
while (true) {
|
||||
// Pace the samples to the desired rate
|
||||
this_thread::sleep_until(tm);
|
||||
// The steady time at which to read the next sample
|
||||
auto tm = steady_clock::now() + 250ms;
|
||||
|
||||
// Pace the sampling by letting the condition variable time out
|
||||
// periodically. When 'cv' is signaled, it's time to quit.
|
||||
unique_lock lk(mtx);
|
||||
|
||||
while (!cv.wait_until(lk, tm, []{ return quit; })) {
|
||||
lk.unlock();
|
||||
|
||||
// Get a timestamp and format as a string
|
||||
time_t t = system_clock::to_time_t(system_clock::now());
|
||||
@ -293,6 +319,7 @@ int main(int argc, char* argv[])
|
||||
top.publish(std::move(payload));
|
||||
|
||||
tm += PERIOD;
|
||||
lk.lock();
|
||||
}
|
||||
|
||||
// Disconnect
|
||||
|
||||
Loading…
Reference in New Issue
Block a user