ESPAsyncWebServer/src/AsyncWebSocket.h

219 lines
7.5 KiB
C
Raw Normal View History

2016-04-23 05:11:32 -07:00
/*
Asynchronous WebServer library for Espressif MCUs
Copyright (c) 2016 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ASYNCWEBSOCKET_H_
#define ASYNCWEBSOCKET_H_
#include <Arduino.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
class AsyncWebSocket;
class AsyncWebSocketResponse;
class AsyncWebSocketClient;
class AsyncWebSocketControl;
typedef struct {
uint8_t message_opcode;
uint32_t num;
uint8_t final;
uint8_t masked;
uint8_t opcode;
uint64_t len;
uint8_t mask[4];
uint64_t index;
} AwsFrameInfo;
typedef enum { WS_DISCONNECTED, WS_CONNECTED, WS_DISCONNECTING } AwsClientStatus;
typedef enum { WS_CONTINUATION, WS_TEXT, WS_BINARY, WS_DISCONNECT = 0x08, WS_PING, WS_PONG } AwsFrameType;
typedef enum { WS_MSG_SENDING, WS_MSG_SENT, WS_MSG_ERROR } AwsMessageStatus;
typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType;
class AsyncWebSocketMessage {
protected:
uint8_t _opcode;
bool _mask;
AwsMessageStatus _status;
public:
AsyncWebSocketMessage * next;
AsyncWebSocketMessage():_opcode(WS_TEXT),_mask(false),_status(WS_MSG_ERROR),next(NULL){}
virtual ~AsyncWebSocketMessage(){}
virtual void ack(size_t len, uint32_t time){}
virtual size_t send(AsyncClient *client){ return 0; }
virtual bool finished(){ return _status != WS_MSG_SENDING; }
virtual bool betweenFrames(){ return false; }
};
class AsyncWebSocketClient {
private:
AsyncClient *_client;
AsyncWebSocket *_server;
uint32_t _clientId;
AwsClientStatus _status;
AsyncWebSocketControl * _controlQueue;
AsyncWebSocketMessage * _messageQueue;
uint8_t _pstate;
AwsFrameInfo _pinfo;
void _queueMessage(AsyncWebSocketMessage *dataMessage);
void _queueControl(AsyncWebSocketControl *controlMessage);
void _runQueue();
public:
AsyncWebSocketClient * next;
AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server);
~AsyncWebSocketClient();
//client id increments for the given server
uint32_t id(){ return _clientId; }
AwsClientStatus status(){ return _status; }
AsyncClient* client(){ return _client; }
IPAddress remoteIP();
uint16_t remotePort();
2016-04-23 05:11:32 -07:00
//control frames
void close(uint16_t code=0, const char * message=NULL);
void ping(uint8_t *data=NULL, size_t len=0);
//data packets
void message(AsyncWebSocketMessage *message){ _queueMessage(message); }
size_t printf(const char *format, ...);
size_t printf_P(PGM_P formatP, ...);
2016-04-23 05:11:32 -07:00
void text(const char * message, size_t len);
void text(const char * message);
void text(uint8_t * message, size_t len);
void text(char * message);
void text(String &message);
void text(const __FlashStringHelper *data);
2016-04-23 05:11:32 -07:00
void binary(const char * message, size_t len);
void binary(const char * message);
void binary(uint8_t * message, size_t len);
void binary(char * message);
void binary(String &message);
void binary(const __FlashStringHelper *data, size_t len);
2016-04-23 05:11:32 -07:00
//system callbacks (do not call)
void _onAck(size_t len, uint32_t time);
void _onError(int8_t);
void _onPoll();
void _onTimeout(uint32_t time);
void _onDisconnect();
void _onData(void *buf, size_t plen);
};
typedef std::function<void(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len)> AwsEventHandler;
//WebServer Handler implementation that plays the role of a socket server
class AsyncWebSocket: public AsyncWebHandler {
private:
String _url;
AsyncWebSocketClient * _clients;
uint32_t _cNextId;
AwsEventHandler _eventHandler;
bool _enabled;
2016-04-23 05:11:32 -07:00
public:
AsyncWebSocket(String url);
~AsyncWebSocket();
const char * url(){ return _url.c_str(); }
void enable(bool e){ _enabled = e; }
bool enabled() { return _enabled; }
2016-04-23 05:11:32 -07:00
size_t count();
AsyncWebSocketClient * client(uint32_t id);
bool hasClient(uint32_t id){ return client(id) != NULL; }
void close(uint32_t id, uint16_t code=0, const char * message=NULL);
void closeAll(uint16_t code=0, const char * message=NULL);
void ping(uint32_t id, uint8_t *data=NULL, size_t len=0);
void pingAll(uint8_t *data=NULL, size_t len=0);
void text(uint32_t id, const char * message, size_t len);
void text(uint32_t id, const char * message);
void text(uint32_t id, uint8_t * message, size_t len);
void text(uint32_t id, char * message);
void text(uint32_t id, String &message);
void text(uint32_t id, const __FlashStringHelper *message);
2016-04-23 05:11:32 -07:00
void textAll(const char * message, size_t len);
void textAll(const char * message);
void textAll(uint8_t * message, size_t len);
void textAll(char * message);
void textAll(String &message);
void textAll(const __FlashStringHelper *message);
2016-04-23 05:11:32 -07:00
void binary(uint32_t id, const char * message, size_t len);
void binary(uint32_t id, const char * message);
void binary(uint32_t id, uint8_t * message, size_t len);
void binary(uint32_t id, char * message);
void binary(uint32_t id, String &message);
void binary(uint32_t id, const __FlashStringHelper *message, size_t len);
2016-04-23 05:11:32 -07:00
void binaryAll(const char * message, size_t len);
void binaryAll(const char * message);
void binaryAll(uint8_t * message, size_t len);
void binaryAll(char * message);
void binaryAll(String &message);
void binaryAll(const __FlashStringHelper *message, size_t len);
2016-04-23 05:11:32 -07:00
void message(uint32_t id, AsyncWebSocketMessage *message);
void messageAll(AsyncWebSocketMessage *message);
size_t printf(uint32_t id, const char *format, ...);
size_t printfAll(const char *format, ...);
size_t printf_P(uint32_t id, PGM_P formatP, ...);
size_t printfAll_P(PGM_P formatP, ...);
2016-04-23 05:11:32 -07:00
//event listener
void onEvent(AwsEventHandler handler){
_eventHandler = handler;
}
//system callbacks (do not call)
uint32_t _getNextId(){ return _cNextId++; }
void _addClient(AsyncWebSocketClient * client);
void _handleDisconnect(AsyncWebSocketClient * client);
void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
bool canHandle(AsyncWebServerRequest *request);
void handleRequest(AsyncWebServerRequest *request);
};
//WebServer response to authenticate the socket and detach the tcp client from the web server request
class AsyncWebSocketResponse: public AsyncWebServerResponse {
private:
String _content;
AsyncWebSocket *_server;
public:
AsyncWebSocketResponse(String key, AsyncWebSocket *server);
void _respond(AsyncWebServerRequest *request);
size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time);
bool _sourceValid(){ return true; }
};
#endif /* ASYNCWEBSOCKET_H_ */