Closed andrzejbluszcz closed 2 weeks ago
You can subclass PicoMQTT::Server
and override on_connected
and on_subscribe
, see:
Thank you for the suggestion. I wish I knew C++ enough to make it. I see that in server.h the functins on_connected() and on_subscribe() are declared only. There are apparently no definitions for them in server.cpp. Does that mean that I should write those to suit my purpose?
No, on_connected
and on_subscribe
are both declared and defined in server.h
, but their bodies are empty (note the {}
after the function names).
Here's how you can override these functions and add a custom logic when a client connects or subscribes to a topic:
class CustomMQTTServer: public PicoMQTT::Server {
protected:
virtual void on_connected(const char * client_id) override {
Serial.println("A new client connected");
}
virtual void on_subscribe(const char * client_id, const char * topic) override {
Serial.println("A client set up a new subscription");
}
};
CustomMQTTServer mqtt;
void setup() {
Serial.begin(115200);
mqtt.begin();
}
void loop() {
mqtt.loop();
}
You can override any other function marked virtual
in the same way.
Thank you very much for your help and patience. I think that closes the issue.
@mlesniew would you mind giving this a try? the above seems not to work for me
https://github.com/mlesniew/PicoMQTT/compare/master...mhaberler:PicoMQTT:custom-server-example
I stumbled on some c++ compiler issue - see updated example with devkit-c config from previous post this conatins a bleeding-edge Arduino platfrom and toolchain as per below:
Executing task: platformio run --environment custom-server-devkitc
Processing custom-server-devkitc (platform: https://github.com/Jason2866/platform-espressif32/releases/download/2024.07.20/platform-espressif32.zip; board: esp32-s3-devkitc-1-32MB-8MB; framework: arduino)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32-s3-devkitc-1-32MB-8MB.html
PLATFORM: Espressif 32 (2024.7.20) > Espressif ESP32-S3-DevKitC-2-opi
HARDWARE: ESP32S3 240MHz, 320KB RAM, 32MB Flash
DEBUG: Current (esp-builtin) On-board (esp-builtin) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
- framework-arduinoespressif32 @ 3.0.2+sha.01c738d
- tool-esptoolpy @ 4.7.5
- tool-mklittlefs @ 3.2.0
- tool-openocd-esp32 @ 2.1100.20220706 (11.0)
- tool-riscv32-esp-elf-gdb @ 12.1.0+20221002
- tool-xtensa-esp-elf-gdb @ 12.1.0+20221002
- toolchain-riscv32-esp @ 13.2.0+20230928
- toolchain-xtensa-esp-elf @ 13.2.0+20230928
Converting custom_server.ino
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 28 compatible libraries
Scanning dependencies...
Dependency Graph
|-- PicoMQTT @ 0.3.8
Building in debug mode
Compiling .pio/build/custom-server-devkitc/src/custom_server.ino.cpp.o
Compiling .pio/build/custom-server-devkitc/lib932/PicoMQTT/PicoMQTT/connection.cpp.o
Compiling .pio/build/custom-server-devkitc/lib932/PicoMQTT/PicoMQTT/server.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/FunctionalInterrupt.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/HEXBuilder.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/HWCDC.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/HardwareSerial.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/IPAddress.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/MD5Builder.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/MacAddress.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/Print.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/SHA1Builder.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/Stream.cpp.o
Compiling .pio/build/custom-server-devkitc/FrameworkArduino/StreamString.cpp.o
lib/PicoMQTT/src/PicoMQTT/connection.cpp: In member function 'void PicoMQTT::Connection::wait_for_reply(PicoMQTT::Packet::Type, std::function<void(PicoMQTT::IncomingPacket&)>)':
lib/PicoMQTT/src/PicoMQTT/connection.cpp:67:24: error: cannot declare variable 'packet' to be of abstract type 'PicoMQTT::IncomingPacket'
67 | IncomingPacket packet(client);
| ^~~~~~
In file included from lib/PicoMQTT/src/PicoMQTT/connection.h:8,
from lib/PicoMQTT/src/PicoMQTT/connection.cpp:2:
lib/PicoMQTT/src/PicoMQTT/incoming_packet.h:10:7: note: because the following virtual functions are pure within 'PicoMQTT::IncomingPacket':
10 | class IncomingPacket: public Packet, public Client {
| ^~~~~~~~~~~~~~
In file included from /Users/mah/.platformio/packages/framework-arduinoespressif32@src-c38c877b286c4329f2d3ff62747e7f12/cores/esp32/Arduino.h:197,
from lib/PicoMQTT/src/PicoMQTT/connection.h:5:
/Users/mah/.platformio/packages/framework-arduinoespressif32@src-c38c877b286c4329f2d3ff62747e7f12/cores/esp32/Client.h:29:15: note: 'virtual int Client::connect(IPAddress, uint16_t, int32_t)'
29 | virtual int connect(IPAddress ip, uint16_t port, int32_t timeout) = 0;
| ^~~~~~~
/Users/mah/.platformio/packages/framework-arduinoespressif32@src-c38c877b286c4329f2d3ff62747e7f12/cores/esp32/Client.h:31:15: note: 'virtual int Client::connect(const char*, uint16_t, int32_t)'
31 | virtual int connect(const char *host, uint16_t port, int32_t timeout) = 0;
| ^~~~~~~
lib/PicoMQTT/src/PicoMQTT/connection.cpp: In member function 'virtual void PicoMQTT::Connection::loop()':
lib/PicoMQTT/src/PicoMQTT/connection.cpp:171:24: error: cannot declare variable 'packet' to be of abstract type 'PicoMQTT::IncomingPacket'
171 | IncomingPacket packet(client);
| ^~~~~~
*** [.pio/build/custom-server-devkitc/lib932/PicoMQTT/PicoMQTT/connection.cpp.o] Error 1
lib/PicoMQTT/src/PicoMQTT/server.cpp: In member function 'virtual void PicoMQTT::BasicServer::Client::on_message(const char*, PicoMQTT::IncomingPacket&)':
lib/PicoMQTT/src/PicoMQTT/server.cpp:133:25: error: cannot declare variable 'incoming_publish' to be of abstract type 'PicoMQTT::BasicServer::IncomingPublish'
133 | IncomingPublish incoming_publish(packet, publish);
| ^~~~~~~~~~~~~~~~
In file included from lib/PicoMQTT/src/PicoMQTT/server.cpp:3:
lib/PicoMQTT/src/PicoMQTT/server.h:55:15: note: because the following virtual functions are pure within 'PicoMQTT::BasicServer::IncomingPublish':
55 | class IncomingPublish: public IncomingPacket {
| ^~~~~~~~~~~~~~~
In file included from /Users/mah/.platformio/packages/framework-arduinoespressif32@src-c38c877b286c4329f2d3ff62747e7f12/cores/esp32/Arduino.h:197,
from lib/PicoMQTT/src/PicoMQTT/server.h:6:
/Users/mah/.platformio/packages/framework-arduinoespressif32@src-c38c877b286c4329f2d3ff62747e7f12/cores/esp32/Client.h:29:15: note: 'virtual int Client::connect(IPAddress, uint16_t, int32_t)'
29 | virtual int connect(IPAddress ip, uint16_t port, int32_t timeout) = 0;
| ^~~~~~~
/Users/mah/.platformio/packages/framework-arduinoespressif32@src-c38c877b286c4329f2d3ff62747e7f12/cores/esp32/Client.h:31:15: note: 'virtual int Client::connect(const char*, uint16_t, int32_t)'
31 | virtual int connect(const char *host, uint16_t port, int32_t timeout) = 0;
| ^~~~~~~
*** [.pio/build/custom-server-devkitc/lib932/PicoMQTT/PicoMQTT/server.cpp.o] Error 1
=================================================================================== [FAILED] Took 2.83 seconds ===================================================================================
Environment Status Duration
--------------------- -------- ------------
custom-server-devkitc FAILED 00:00:02.825
From the build log it looks like you're not using the latest PicoMQTT version. Can you check if this also happens with version 1.1.1?
yes, sorry about that - switching to 1.1.1 adressed the first question
build succeeds with the 8.4 toolchain brought by platform = espressif32@6.7.0
PACKAGES:
- framework-arduinoespressif32 @ 3.20016.0 (2.0.16)
- tool-esptoolpy @ 1.40501.0 (4.5.1)
- tool-openocd-esp32 @ 2.1100.20220706 (11.0)
- toolchain-riscv32-esp @ 8.4.0+2021r2-patch5
- toolchain-xtensa-esp32s3 @ 8.4.0+2021r2-patch5
second issue still remains but that is likely my low C++ fu - trying the (unsupported) platform package
platform = https://github.com/Jason2866/platform-espressif32/releases/download/2024.07.20/platform-espressif32.zip
brings in the 13.2.0 toolchain which seems to be more picky:
PACKAGES:
- framework-arduinoespressif32 @ 3.0.2+sha.01c738d
- tool-esptoolpy @ 4.7.5
- tool-mklittlefs @ 3.2.0
- tool-openocd-esp32 @ 2.1100.20220706 (11.0)
- tool-riscv32-esp-elf-gdb @ 12.1.0+20221002
- tool-xtensa-esp-elf-gdb @ 12.1.0+20221002
- toolchain-riscv32-esp @ 13.2.0+20230928
- toolchain-xtensa-esp-elf @ 13.2.0+20230928
In file included from lib/PicoMQTT/src/PicoMQTT/client.h:5,
from lib/PicoMQTT/src/PicoMQTT.h:19,
from /Users/mah/Ballon/src/BalloonWare/networking/PicoMQTT/examples/custom_server/custom_server.ino:5:
lib/PicoMQTT/src/PicoMQTT/connection.h:64:23: error: cannot declare field 'PicoMQTT::Connection::client' to be of abstract type 'PicoMQTT::ClientWrapper'
64 | ClientWrapper client;
| ^~~~~~
In file included from lib/PicoMQTT/src/PicoMQTT/connection.h:8:
lib/PicoMQTT/src/PicoMQTT/client_wrapper.h:7:7: note: because the following virtual functions are pure within 'PicoMQTT::ClientWrapper':
7 | class ClientWrapper: public ::Client {
| ^~~~~~~~~~~~~
not sure it's worth investigating, I'd just like to understand why
that was too quick: with v1.1.1 and platform = espressif32@6.7.0
the example builds
however the callbacks are NOT executed
Try replacing
CustomMQTTServer::Server mqtt;
With
CustomMQTTServer mqtt;
that did it, sorry for the snafu
would you mind sketching how this would work in the multi_server example?
the subclassing as suggested above doesnt work in this case, looks like advanced templatology is required if I try like so:
CustomMQTTServer mqtt(mqtt_tcp_server, websocket_server);
Compiling .pio/build/custom-server-devkitc/src/custom_server.ino.cpp.o
/Users/mah/Ballon/src/BalloonWare/networking/PicoMQTT/examples/custom_server/custom_server.ino:41:56: error: no matching function for call to 'CustomMQTTServer::CustomMQTTServer(WiFiServer&, WiFiServer&)'
CustomMQTTServer mqtt(mqtt_tcp_server, websocket_server);
^
/Users/mah/Ballon/src/BalloonWare/networking/PicoMQTT/examples/custom_server/custom_server.ino:20:7: note: candidate: 'CustomMQTTServer::CustomMQTTServer()'
class CustomMQTTServer: public PicoMQTT::Server {
^~~~~~~~~~~~~~~~
/Users/mah/Ballon/src/BalloonWare/networking/PicoMQTT/examples/custom_server/custom_server.ino:20:7: note: candidate expects 0 arguments, 2 provided
/Users/mah/Ballon/src/BalloonWare/networking/PicoMQTT/examples/custom_server/custom_server.ino:20:7: note: candidate: 'CustomMQTTServer::CustomMQTTServer(CustomMQTTServer&&)'
/Users/mah/Ballon/src/BalloonWare/networking/PicoMQTT/examples/custom_server/custom_server.ino:20:7: note: candidate expects 1 argument, 2 provided
*** [.pio/build/custom-server-devkitc/src/custom_server.ino.cpp.o] Error 1
Sorry, I missed this question before.
There reason it's not working is that CustomMQTTServer
doesn't have any constructor defined. This makes the compiler create a constructor automatically, which calls the default constructor ofPicoMQTT::Server
.
To make CustomMQTTServer
inherit its parent's constructors, we have to explicitly request it with the using
keyword like this:
class CustomMQTTServer: public PicoMQTT::Server {
using PicoMQTT::Server::Server;
...
};
Hi! How to know what are current subscriptions? Or, does Server notify about a new connection/subscription?
Thank you.