@@ -291,7 +291,7 @@ class AsyncWebSocket : public AsyncWebHandler {
291291 String _url;
292292 std::list<AsyncWebSocketClient> _clients;
293293 uint32_t _cNextId;
294- AwsEventHandler _eventHandler{ nullptr } ;
294+ AwsEventHandler _eventHandler;
295295 AwsHandshakeHandler _handshakeHandler;
296296 bool _enabled;
297297#ifdef ESP32
@@ -305,8 +305,8 @@ class AsyncWebSocket : public AsyncWebHandler {
305305 PARTIALLY_ENQUEUED = 2 ,
306306 } SendStatus;
307307
308- explicit AsyncWebSocket (const char *url) : _url(url), _cNextId(1 ), _enabled(true ) {}
309- AsyncWebSocket (const String &url) : _url(url), _cNextId(1 ), _enabled(true ) {}
308+ explicit AsyncWebSocket (const char *url, AwsEventHandler handler = nullptr ) : _url(url), _cNextId(1 ), _eventHandler(handler ), _enabled(true ) {}
309+ AsyncWebSocket (const String &url, AwsEventHandler handler = nullptr ) : _url(url), _cNextId(1 ), _eventHandler(handler ), _enabled(true ) {}
310310 ~AsyncWebSocket (){};
311311 const char *url () const {
312312 return _url.c_str ();
@@ -413,4 +413,86 @@ class AsyncWebSocketResponse : public AsyncWebServerResponse {
413413 }
414414};
415415
416+ class AsyncWebSocketMessageHandler {
417+ public:
418+ AwsEventHandler eventHandler () const {
419+ return _handler;
420+ }
421+
422+ void onConnect (std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client)> onConnect) {
423+ _onConnect = onConnect;
424+ }
425+
426+ void onDisconnect (std::function<void (AsyncWebSocket *server, uint32_t clientId)> onDisconnect) {
427+ _onDisconnect = onDisconnect;
428+ }
429+
430+ /* *
431+ * Error callback
432+ * @param reason null-terminated string
433+ * @param len length of the string
434+ */
435+ void onError (std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client, uint16_t errorCode, const char *reason, size_t len)> onError) {
436+ _onError = onError;
437+ }
438+
439+ /* *
440+ * Complete message callback
441+ * @param data pointer to the data (binary or null-terminated string). This handler expects the user to know which data type he uses.
442+ */
443+ void onMessage (std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client, const uint8_t *data, size_t len)> onMessage) {
444+ _onMessage = onMessage;
445+ }
446+
447+ /* *
448+ * Fragmented message callback
449+ * @param data pointer to the data (binary or null-terminated string), will be null-terminated. This handler expects the user to know which data type he uses.
450+ */
451+ // clang-format off
452+ void onFragment (std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client, const AwsFrameInfo *frameInfo, const uint8_t *data, size_t len)> onFragment) {
453+ _onFragment = onFragment;
454+ }
455+ // clang-format on
456+
457+ private:
458+ // clang-format off
459+ std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client)> _onConnect;
460+ std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client, uint16_t errorCode, const char *reason, size_t len)> _onError;
461+ std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client, const uint8_t *data, size_t len)> _onMessage;
462+ std::function<void (AsyncWebSocket *server, AsyncWebSocketClient *client, const AwsFrameInfo *frameInfo, const uint8_t *data, size_t len)> _onFragment;
463+ std::function<void (AsyncWebSocket *server, uint32_t clientId)> _onDisconnect;
464+ // clang-format on
465+
466+ // this handler is meant to only support 1-frame messages (== unfragmented messages)
467+ AwsEventHandler _handler = [this ](AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
468+ if (type == WS_EVT_CONNECT) {
469+ if (_onConnect) {
470+ _onConnect (server, client);
471+ }
472+ } else if (type == WS_EVT_DISCONNECT) {
473+ if (_onDisconnect) {
474+ _onDisconnect (server, client->id ());
475+ }
476+ } else if (type == WS_EVT_ERROR) {
477+ if (_onError) {
478+ _onError (server, client, *((uint16_t *)arg), (const char *)data, len);
479+ }
480+ } else if (type == WS_EVT_DATA) {
481+ AwsFrameInfo *info = (AwsFrameInfo *)arg;
482+ if (info->opcode == WS_TEXT) {
483+ data[len] = 0 ;
484+ }
485+ if (info->final && info->index == 0 && info->len == len) {
486+ if (_onMessage) {
487+ _onMessage (server, client, data, len);
488+ }
489+ } else {
490+ if (_onFragment) {
491+ _onFragment (server, client, info, data, len);
492+ }
493+ }
494+ }
495+ };
496+ };
497+
416498#endif /* ASYNCWEBSOCKET_H_ */
0 commit comments