├── .gitignore ├── .vscode └── c_cpp_properties.json ├── README.md ├── WebSocketClient250.h ├── WebSocketStreamClient.h ├── examples └── example-mqtt-ws │ └── example-mqtt-ws.ino └── library.properties /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ipch/ 2 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Win32", 5 | "includePath": [ 6 | "${env:USERPROFILE}/Documents/Arduino/libraries/ArduinoHttpClient/src", 7 | "${workspaceFolder}/**" 8 | ], 9 | "defines": [ 10 | "_DEBUG", 11 | "UNICODE", 12 | "_UNICODE" 13 | ], 14 | "windowsSdkVersion": "10.0.17134.0", 15 | "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.15.26726/bin/Hostx64/x64/cl.exe", 16 | "cStandard": "c11", 17 | "cppStandard": "c++17", 18 | "intelliSenseMode": "msvc-x64" 19 | } 20 | ], 21 | "version": 4 22 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebSocketStreamClient 2 | 3 | A WebSocketClient that implements Client.h so that the PubSubClient MQTT library can use it - with wss or ws. 4 | 5 | ## Dependencies 6 | 7 | * [ArduinoHttpClient 0.4.0](https://github.com/arduino-libraries/ArduinoHttpClient) and all of it's dependencys. Because this works with esp8266/2.4.2 but not with esp8266/2.5.0, use the supplied WebSocketClient250 class instead. 8 | 9 | Tested with esp8266/2.5.0 Board libraries. There is an example node.js server that you can use here with this library at [web-socket-mqtt](https://github.com/areve/web-socket-mqtt). 10 | 11 | ## Usage 12 | 13 | See examples folder for a complete program. 14 | 15 | ```cpp 16 | 17 | void onMqttPublish(char *topic, byte *payload, unsigned int length) 18 | { 19 | // handle mqtt messages here 20 | } 21 | 22 | WiFiClientSecure wiFiClient; 23 | WebSocketClient250 wsClient(wiFiClient, host, port); 24 | WebSocketStreamClient wsStreamClient(wsClient, path); 25 | PubSubClient mqtt(wsStreamClient); 26 | 27 | wiFiClient.setFingerprint(fingerprint); 28 | mqtt.setCallback(onMqttPublish); 29 | 30 | if (mqtt.connect("your_identifier")) 31 | { 32 | mqtt.publish("topic1", "hello world"); 33 | mqtt.subscribe("topic2"); 34 | } 35 | 36 | ``` -------------------------------------------------------------------------------- /WebSocketClient250.h: -------------------------------------------------------------------------------- 1 | #ifndef __WEBSOCKETCLIENTUPGRADED_H_ 2 | #define __WEBSOCKETCLIENTUPGRADED_H_ 3 | 4 | #include 5 | 6 | class WebSocketClient250 : public WebSocketClient 7 | { 8 | public: 9 | WebSocketClient250(WiFiClientSecure &wiFiClient, const char *host, uint16_t port) 10 | : WebSocketClient(wiFiClient, host, port) 11 | { 12 | } 13 | 14 | int connect(const IPAddress &ip, uint16_t port) 15 | { 16 | return WebSocketClient::connect(ip, port); 17 | } 18 | 19 | bool flush(unsigned int maxWaitMs = 0) 20 | { 21 | WebSocketClient::flush(); 22 | return true; 23 | } 24 | 25 | bool stop(unsigned int maxWaitMs = 0) 26 | { 27 | WebSocketClient::stop(); 28 | return true; 29 | } 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /WebSocketStreamClient.h: -------------------------------------------------------------------------------- 1 | #ifndef __WEBSOCKETSTREAMCLIENT_H_ 2 | #define __WEBSOCKETSTREAMCLIENT_H_ 3 | 4 | #include 5 | #include "WebSocketClient250.h" 6 | #include 7 | 8 | class WebSocketStreamClient : public Client 9 | { 10 | public: 11 | WebSocketStreamClient(WebSocketClient250 &webSocketClient, const char *path) 12 | { 13 | _webSocketClient = &webSocketClient; 14 | _path = path; 15 | } 16 | 17 | int connect(const IPAddress ip, uint16_t port) 18 | { 19 | _webSocketClient->begin(_path); 20 | return 1; 21 | } 22 | 23 | int connect(const char *host, uint16_t port) 24 | { 25 | _webSocketClient->begin(_path); 26 | return 1; 27 | } 28 | 29 | size_t write(uint8_t b) 30 | { 31 | if (!connected()) 32 | return -1; 33 | return write(&b, 1); 34 | } 35 | 36 | size_t write(const uint8_t *buf, size_t size) 37 | { 38 | if (!connected()) 39 | return -1; 40 | _webSocketClient->beginMessage(TYPE_BINARY); 41 | _webSocketClient->write(buf, size); 42 | _webSocketClient->endMessage(); 43 | return size; 44 | } 45 | 46 | int available() 47 | { 48 | if (!connected()) 49 | return 0; 50 | if (_webSocketClient->available() == 0) 51 | _webSocketClient->parseMessage(); 52 | return _webSocketClient->available(); 53 | } 54 | 55 | int read() 56 | { 57 | if (!connected() || !available()) 58 | return -1; 59 | return _webSocketClient->read(); 60 | } 61 | 62 | int read(uint8_t *buf, size_t size) 63 | { 64 | if (!connected() || !available()) 65 | return -1; 66 | return _webSocketClient->read(buf, size); 67 | } 68 | 69 | int peek() 70 | { 71 | if (!connected() || !available()) 72 | return -1; 73 | return _webSocketClient->peek(); 74 | } 75 | 76 | void flush() { 77 | if (!connected()) 78 | return; 79 | _webSocketClient->flush(); 80 | return; 81 | } 82 | 83 | void stop() 84 | { 85 | if (!connected()) 86 | return; 87 | _webSocketClient->stop(); 88 | return; 89 | } 90 | 91 | uint8_t connected() 92 | { 93 | return _webSocketClient->connected(); 94 | } 95 | 96 | operator bool() 97 | { 98 | return _webSocketClient != NULL; 99 | } 100 | 101 | private: 102 | WebSocketClient250 *_webSocketClient; 103 | const char *_path; 104 | }; 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /examples/example-mqtt-ws/example-mqtt-ws.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "WebSocketStreamClient.h" 5 | #include "WebSocketClient250.h" 6 | 7 | #define DEBUG_MAIN(...) Serial.printf(__VA_ARGS__) 8 | 9 | #ifndef DEBUG_MAIN 10 | #define DEBUG_MAIN(...) 11 | #endif 12 | 13 | // config 14 | const char *ssid = "YOURSSID"; 15 | const char *password = "YOURPASSWORD"; 16 | const char *host = (char *)"web-socket-mqtt.herokuapp.com"; 17 | const int port = 443; 18 | const char *fingerprint = "08 3B 71 72 02 43 6E CA ED 42 86 93 BA 7E DF 81 C4 BC 62 30"; 19 | const char *path = (char *)"/mqtt"; 20 | 21 | // globals 22 | unsigned int counter = 0; 23 | unsigned long lastPublishTime = 0; 24 | unsigned long publishInterval = 1000; 25 | uint8_t buffer[1000]; 26 | 27 | void onMqttPublish(char *topic, byte *payload, unsigned int length) 28 | { 29 | DEBUG_MAIN("received %s %.*s\n", topic, length, payload); 30 | } 31 | 32 | WiFiClientSecure wiFiClient; 33 | WebSocketClient250 wsClient(wiFiClient, host, port); 34 | WebSocketStreamClient wsStreamClient(wsClient, path); 35 | PubSubClient mqtt(wsStreamClient); 36 | 37 | void setup() 38 | { 39 | Serial.begin(9600); 40 | delay(2000); 41 | 42 | DEBUG_MAIN("WiFi connecting to %s\n", ssid); 43 | WiFi.disconnect(); 44 | WiFi.begin(ssid, password); 45 | while (WiFi.status() != WL_CONNECTED) 46 | { 47 | DEBUG_MAIN("."); 48 | delay(500); 49 | } 50 | DEBUG_MAIN("\nWiFi connected to %s\n", WiFi.SSID().c_str()); 51 | 52 | wiFiClient.setFingerprint(fingerprint); 53 | mqtt.setCallback(onMqttPublish); 54 | 55 | DEBUG_MAIN("mqtt connecting\n"); 56 | if (mqtt.connect("topic1")) 57 | { 58 | DEBUG_MAIN("mqtt connected OK\n"); 59 | mqtt.publish("log", "hello world"); 60 | mqtt.subscribe("topic1"); 61 | } 62 | } 63 | 64 | void loop() 65 | { 66 | mqtt.loop(); 67 | if (lastPublishTime + publishInterval < millis()) 68 | { 69 | lastPublishTime = millis(); 70 | DEBUG_MAIN("tick %d\n", ++counter); 71 | if (mqtt.connected()) 72 | { 73 | String msg = (String("esp8266 counter ") + String(counter)); 74 | mqtt.publish("log", msg.c_str()); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=WebSocketStreamClient 2 | version=0.1.0 3 | author=Areve 4 | maintainer=Areve 5 | sentence=A WebSocketClient that can be used with PubSubClient for MQTT over WebSockets. 6 | paragraph=A WebSocketClient that implements Client.h so that the PubSubClient MQTT library can use it - with wss or ws 7 | category=Communication 8 | url=https://github.com/areve/WebSocketStreamClient 9 | architectures=* 10 | includes=WebSocketStreamClient.h 11 | depends=ArduinoHttpClient 12 | --------------------------------------------------------------------------------