Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
4.2 KiB

  1. /*
  2. WEBSOCKET MODULE
  3. Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. Copyright (C) 2019 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
  5. */
  6. #pragma once
  7. #include "espurna.h"
  8. #include <ArduinoJson.h>
  9. #include <queue>
  10. #include <functional>
  11. #include <vector>
  12. #include "web.h"
  13. #include "utils.h"
  14. // Generalized WS lifetime callbacks.
  15. // Each callback is kept as std::function, thus we can use complex objects, and not just basic function pointers.
  16. //
  17. // Connection start:
  18. // - on_visible will be the very first message sent, callback data will be grouped together
  19. // - on_connected is sent next, but each callback's data will be sent separately
  20. // - on_data is the final one, each callback is executed separately
  21. //
  22. // While connected:
  23. // - on_action will be ran whenever we receive special JSON 'action' payload
  24. // - on_keycheck will be used to determine if we can handle specific settings keys
  25. using ws_on_send_callback_f = std::function<void(JsonObject& root)>;
  26. using ws_on_action_callback_f = std::function<void(uint32_t client_id, const char * action, JsonObject& data)>;
  27. using ws_on_keycheck_callback_f = std::function<bool(const char * key, JsonVariant& value)>;
  28. using ws_on_send_callback_list_t = std::vector<ws_on_send_callback_f>;
  29. using ws_on_action_callback_list_t = std::vector<ws_on_action_callback_f>;
  30. using ws_on_keycheck_callback_list_t = std::vector<ws_on_keycheck_callback_f>;
  31. struct ws_callbacks_t {
  32. ws_callbacks_t& onVisible(ws_on_send_callback_f);
  33. ws_callbacks_t& onConnected(ws_on_send_callback_f);
  34. ws_callbacks_t& onData(ws_on_send_callback_f);
  35. ws_callbacks_t& onAction(ws_on_action_callback_f);
  36. ws_callbacks_t& onKeyCheck(ws_on_keycheck_callback_f);
  37. ws_on_send_callback_list_t on_visible;
  38. ws_on_send_callback_list_t on_connected;
  39. ws_on_send_callback_list_t on_data;
  40. ws_on_action_callback_list_t on_action;
  41. ws_on_keycheck_callback_list_t on_keycheck;
  42. };
  43. // Postponed debug messages. best-effort, will not be re-scheduled when ws queue is full
  44. bool wsDebugSend(const char* prefix, const char* message);
  45. // Postponed json messages. schedules callback(s) to be called when resources to do so are available.
  46. // Queued item is removed on client disconnection *or* when internal timeout occurs
  47. // There are two policies set on how to send the data:
  48. // - All will use the same JsonObject for each callback
  49. // - Sequence will use a different JsonObject for each callback
  50. // Default is All
  51. //
  52. // WARNING: callback lists are taken by reference! make sure that list is ether:
  53. // - std::move(...)'ed to give control of the callback list to us
  54. // - persistent and will be available after the current block ends (global, heap-allocated, etc.)
  55. // de-allocation is not expected e.g. ws_callbacks_t from wsRegister() is never destroyed
  56. void wsPost(uint32_t client_id, ws_on_send_callback_f&& cb);
  57. void wsPost(ws_on_send_callback_f&& cb);
  58. void wsPost(uint32_t client_id, const ws_on_send_callback_f& cb);
  59. void wsPost(const ws_on_send_callback_f& cb);
  60. void wsPostAll(uint32_t client_id, ws_on_send_callback_list_t&& cbs);
  61. void wsPostAll(ws_on_send_callback_list_t&& cbs);
  62. void wsPostAll(uint32_t client_id, const ws_on_send_callback_list_t& cbs);
  63. void wsPostAll(const ws_on_send_callback_list_t& cbs);
  64. void wsPostSequence(uint32_t client_id, ws_on_send_callback_list_t&& cbs);
  65. void wsPostSequence(ws_on_send_callback_list_t&& cbs);
  66. void wsPostSequence(uint32_t client_id, const ws_on_send_callback_list_t& cbs);
  67. void wsPostSequence(const ws_on_send_callback_list_t& cbs);
  68. // Immmediatly try to serialize and send JsonObject&
  69. // May silently fail when network is busy sending previous requests
  70. void wsSend(JsonObject& root);
  71. void wsSend(uint32_t client_id, JsonObject& root);
  72. void wsSend(JsonObject& root);
  73. void wsSend(ws_on_send_callback_f callback);
  74. void wsSend(const char* data);
  75. // Immediatly try to serialize and send raw char data
  76. // (also, see above)
  77. void wsSend_P(PGM_P data);
  78. void wsSend_P(uint32_t client_id, PGM_P data);
  79. // Check if any or specific client_id is connected
  80. // Server will try to set unique ID for each client
  81. bool wsConnected();
  82. bool wsConnected(uint32_t client_id);
  83. // Access to our module-specific lifetime callbacks.
  84. // Expected usage is through the on() methods
  85. ws_callbacks_t& wsRegister();
  86. void wsSetup();