mirror of
https://github.com/Links2004/arduinoWebSockets.git
synced 2025-07-14 15:56:30 +02:00
add possibility to add Header To Payload to save one TCP package
see #12
This commit is contained in:
@ -60,8 +60,11 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea
|
||||
* @param opcode WSopcode_t
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param mask bool add dummy mask to the frame (needed for web browser)
|
||||
* @param fin bool can be used to send data in more then one frame (set fin on the last frame)
|
||||
* @param headerToPayload bool set true if the payload has reserved 14 Byte at the beginning to dynamically add the Header (payload neet to be in RAM!)
|
||||
*/
|
||||
void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin) {
|
||||
void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) {
|
||||
|
||||
if(!client->tcp.connected()) {
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num);
|
||||
@ -74,49 +77,72 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
|
||||
}
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send massage frame -------\n", client->num);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u\n", client->num, fin, opcode, mask, length);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u headerToPayload: %u\n", client->num, fin, opcode, mask, length, headerToPayload);
|
||||
|
||||
if(opcode == WSop_text) {
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, payload);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, (payload + (headerToPayload ? 14 : 0)));
|
||||
}
|
||||
|
||||
uint8_t maskKey[4] = { 0 };
|
||||
uint8_t buffer[16] = { 0 };
|
||||
uint8_t i = 0;
|
||||
uint8_t buffer[14] = { 0 };
|
||||
|
||||
//create header
|
||||
uint8_t headerSize;
|
||||
uint8_t * headerPtr;
|
||||
|
||||
// calculate header Size
|
||||
if(length < 126) {
|
||||
headerSize = 2;
|
||||
} else if(length < 0xFFFF) {
|
||||
headerSize = 4;
|
||||
} else {
|
||||
headerSize = 10;
|
||||
}
|
||||
|
||||
if(mask) {
|
||||
headerSize += 4;
|
||||
}
|
||||
|
||||
// set Header Pointer
|
||||
if(headerToPayload) {
|
||||
// calculate offset in payload
|
||||
headerPtr = (payload + (14 - headerSize));
|
||||
} else {
|
||||
headerPtr = &buffer[0];
|
||||
}
|
||||
|
||||
// create header
|
||||
|
||||
// byte 0
|
||||
buffer[i] = 0x00;
|
||||
*headerPtr = 0x00;
|
||||
if(fin) {
|
||||
buffer[i] |= bit(7); ///< set Fin
|
||||
*headerPtr |= bit(7); ///< set Fin
|
||||
}
|
||||
buffer[i++] |= opcode; ///< set opcode
|
||||
*headerPtr |= opcode; ///< set opcode
|
||||
headerPtr++;
|
||||
|
||||
// byte 1
|
||||
buffer[i] = 0x00;
|
||||
*headerPtr = 0x00;
|
||||
if(mask) {
|
||||
buffer[i] |= bit(7); ///< set mask
|
||||
*headerPtr |= bit(7); ///< set mask
|
||||
}
|
||||
|
||||
if(length < 126) {
|
||||
buffer[i++] |= length;
|
||||
|
||||
*headerPtr |= length; headerPtr++;
|
||||
} else if(length < 0xFFFF) {
|
||||
buffer[i++] |= 126;
|
||||
buffer[i++] = ((length >> 8) & 0xFF);
|
||||
buffer[i++] = (length & 0xFF);
|
||||
*headerPtr |= 126; headerPtr++;
|
||||
*headerPtr = ((length >> 8) & 0xFF); headerPtr++;
|
||||
*headerPtr = (length & 0xFF); headerPtr++;
|
||||
} else {
|
||||
// normaly we never get here (to less memory)
|
||||
buffer[i++] |= 127;
|
||||
buffer[i++] = 0x00;
|
||||
buffer[i++] = 0x00;
|
||||
buffer[i++] = 0x00;
|
||||
buffer[i++] = 0x00;
|
||||
buffer[i++] = ((length >> 24) & 0xFF);
|
||||
buffer[i++] = ((length >> 16) & 0xFF);
|
||||
buffer[i++] = ((length >> 8) & 0xFF);
|
||||
buffer[i++] = (length & 0xFF);
|
||||
*headerPtr |= 127; headerPtr++;
|
||||
*headerPtr = 0x00; headerPtr++;
|
||||
*headerPtr = 0x00; headerPtr++;
|
||||
*headerPtr = 0x00; headerPtr++;
|
||||
*headerPtr = 0x00; headerPtr++;
|
||||
*headerPtr = ((length >> 24) & 0xFF); headerPtr++;
|
||||
*headerPtr = ((length >> 16) & 0xFF); headerPtr++;
|
||||
*headerPtr = ((length >> 8) & 0xFF); headerPtr++;
|
||||
*headerPtr = (length & 0xFF); headerPtr++;
|
||||
}
|
||||
|
||||
if(mask) {
|
||||
@ -124,23 +150,29 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
|
||||
for(uint8_t x = 0; x < sizeof(maskKey); x++) {
|
||||
// maskKey[x] = random(0xFF);
|
||||
maskKey[x] = 0x00; // fake xor (0x00 0x00 0x00 0x00)
|
||||
buffer[i++] = maskKey[x];
|
||||
*headerPtr = maskKey[x]; headerPtr++;
|
||||
}
|
||||
|
||||
// todo encode XOR
|
||||
// todo encode XOR (note: using payload not working for static content from flash)
|
||||
//for(size_t x = 0; x < length; x++) {
|
||||
// payload[x] = (payload[x] ^ maskKey[x % 4]);
|
||||
//}
|
||||
}
|
||||
|
||||
if(headerToPayload) {
|
||||
// header has be added to payload
|
||||
// payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings
|
||||
// offset in payload is calculatetd 14 - headerSize
|
||||
client->tcp.write(&payload[(14 - headerSize)], (length + headerSize));
|
||||
} else {
|
||||
// send header
|
||||
client->tcp.write(&buffer[0], i);
|
||||
client->tcp.write(&buffer[0], headerSize);
|
||||
|
||||
if(payload && length > 0) {
|
||||
// send payload
|
||||
client->tcp.write(&payload[0], length);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +106,7 @@ class WebSockets {
|
||||
virtual void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length);
|
||||
|
||||
void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0);
|
||||
void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true);
|
||||
void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false);
|
||||
|
||||
|
||||
void handleWebsocket(WSclient_t * client);
|
||||
|
@ -103,13 +103,14 @@ void WebSocketsClient::onEvent(WebSocketClientEvent cbEvent) {
|
||||
* @param num uint8_t client id
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
*/
|
||||
void WebSocketsClient::sendTXT(uint8_t * payload, size_t length) {
|
||||
void WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPayload) {
|
||||
if(length == 0) {
|
||||
length = strlen((const char *) payload);
|
||||
}
|
||||
if(clientIsConnected(&_client)) {
|
||||
sendFrame(&_client, WSop_text, payload, length, true);
|
||||
sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload);
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,8 +118,8 @@ void WebSocketsClient::sendTXT(const uint8_t * payload, size_t length) {
|
||||
sendTXT((uint8_t *) payload, length);
|
||||
}
|
||||
|
||||
void WebSocketsClient::sendTXT(char * payload, size_t length) {
|
||||
sendTXT((uint8_t *) payload, length);
|
||||
void WebSocketsClient::sendTXT(char * payload, size_t length, bool headerToPayload) {
|
||||
sendTXT((uint8_t *) payload, length, headerToPayload);
|
||||
}
|
||||
|
||||
void WebSocketsClient::sendTXT(const char * payload, size_t length) {
|
||||
@ -134,10 +135,11 @@ void WebSocketsClient::sendTXT(String payload) {
|
||||
* @param num uint8_t client id
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
*/
|
||||
void WebSocketsClient::sendBIN(uint8_t * payload, size_t length) {
|
||||
void WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPayload) {
|
||||
if(clientIsConnected(&_client)) {
|
||||
sendFrame(&_client, WSop_binary, payload, length, true);
|
||||
sendFrame(&_client, WSop_binary, payload, length, true, true, headerToPayload);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,13 +54,13 @@ class WebSocketsClient: private WebSockets {
|
||||
|
||||
void onEvent(WebSocketClientEvent cbEvent);
|
||||
|
||||
void sendTXT(uint8_t * payload, size_t length = 0);
|
||||
void sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false);
|
||||
void sendTXT(const uint8_t * payload, size_t length = 0);
|
||||
void sendTXT(char * payload, size_t length = 0);
|
||||
void sendTXT(char * payload, size_t length = 0, bool headerToPayload = false);
|
||||
void sendTXT(const char * payload, size_t length = 0);
|
||||
void sendTXT(String payload);
|
||||
|
||||
void sendBIN(uint8_t * payload, size_t length);
|
||||
void sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
|
||||
void sendBIN(const uint8_t * payload, size_t length);
|
||||
|
||||
void disconnect(void);
|
||||
|
@ -85,8 +85,9 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) {
|
||||
* @param num uint8_t client id
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
*/
|
||||
void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length) {
|
||||
void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
|
||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||
return;
|
||||
}
|
||||
@ -95,7 +96,7 @@ void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length) {
|
||||
}
|
||||
WSclient_t * client = &_clients[num];
|
||||
if(clientIsConnected(client)) {
|
||||
sendFrame(client, WSop_text, payload, length);
|
||||
sendFrame(client, WSop_text, payload, length, false, true, headerToPayload);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,8 +104,8 @@ void WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t leng
|
||||
sendTXT(num, (uint8_t *) payload, length);
|
||||
}
|
||||
|
||||
void WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length) {
|
||||
sendTXT(num, (uint8_t *) payload, length);
|
||||
void WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) {
|
||||
sendTXT(num, (uint8_t *) payload, length, headerToPayload);
|
||||
}
|
||||
|
||||
void WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) {
|
||||
@ -119,8 +120,9 @@ void WebSocketsServer::sendTXT(uint8_t num, String payload) {
|
||||
* send text data to client all
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
*/
|
||||
void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length) {
|
||||
void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) {
|
||||
WSclient_t * client;
|
||||
if(length == 0) {
|
||||
length = strlen((const char *) payload);
|
||||
@ -129,7 +131,7 @@ void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length) {
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
client = &_clients[i];
|
||||
if(clientIsConnected(client)) {
|
||||
sendFrame(client, WSop_text, payload, length);
|
||||
sendFrame(client, WSop_text, payload, length, false, true, headerToPayload);
|
||||
}
|
||||
#ifdef ESP8266
|
||||
delay(0);
|
||||
@ -141,8 +143,8 @@ void WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) {
|
||||
broadcastTXT((uint8_t *) payload, length);
|
||||
}
|
||||
|
||||
void WebSocketsServer::broadcastTXT(char * payload, size_t length) {
|
||||
broadcastTXT((uint8_t *) payload, length);
|
||||
void WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) {
|
||||
broadcastTXT((uint8_t *) payload, length, headerToPayload);
|
||||
}
|
||||
|
||||
void WebSocketsServer::broadcastTXT(const char * payload, size_t length) {
|
||||
@ -158,14 +160,15 @@ void WebSocketsServer::broadcastTXT(String payload) {
|
||||
* @param num uint8_t client id
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
*/
|
||||
void WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length) {
|
||||
void WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
|
||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||
return;
|
||||
}
|
||||
WSclient_t * client = &_clients[num];
|
||||
if(clientIsConnected(client)) {
|
||||
sendFrame(client, WSop_binary, payload, length);
|
||||
sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,13 +180,14 @@ void WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t leng
|
||||
* send binary data to client all
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
*/
|
||||
void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length) {
|
||||
void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) {
|
||||
WSclient_t * client;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
client = &_clients[i];
|
||||
if(clientIsConnected(client)) {
|
||||
sendFrame(client, WSop_binary, payload, length);
|
||||
sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload);
|
||||
}
|
||||
#ifdef ESP8266
|
||||
delay(0);
|
||||
|
@ -58,22 +58,22 @@ public:
|
||||
void onEvent(WebSocketServerEvent cbEvent);
|
||||
|
||||
|
||||
void sendTXT(uint8_t num, uint8_t * payload, size_t length = 0);
|
||||
void sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false);
|
||||
void sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0);
|
||||
void sendTXT(uint8_t num, char * payload, size_t length = 0);
|
||||
void sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false);
|
||||
void sendTXT(uint8_t num, const char * payload, size_t length = 0);
|
||||
void sendTXT(uint8_t num, String payload);
|
||||
|
||||
void broadcastTXT(uint8_t * payload, size_t length = 0);
|
||||
void broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false);
|
||||
void broadcastTXT(const uint8_t * payload, size_t length = 0);
|
||||
void broadcastTXT(char * payload, size_t length = 0);
|
||||
void broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false);
|
||||
void broadcastTXT(const char * payload, size_t length = 0);
|
||||
void broadcastTXT(String payload);
|
||||
|
||||
void sendBIN(uint8_t num, uint8_t * payload, size_t length);
|
||||
void sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false);
|
||||
void sendBIN(uint8_t num, const uint8_t * payload, size_t length);
|
||||
|
||||
void broadcastBIN(uint8_t * payload, size_t length);
|
||||
void broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
|
||||
void broadcastBIN(const uint8_t * payload, size_t length);
|
||||
|
||||
void disconnect(void);
|
||||
|
Reference in New Issue
Block a user