Skip to content

Commit 39f912b

Browse files
committed
add possibility to add Header To Payload to save one TCP package
see #12
1 parent ad1e609 commit 39f912b

6 files changed

+100
-62
lines changed

src/WebSockets.cpp

+66-34
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,15 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea
5656

5757
/**
5858
*
59-
* @param client WSclient_t * ptr to the client struct
59+
* @param client WSclient_t * ptr to the client struct
6060
* @param opcode WSopcode_t
6161
* @param payload uint8_t *
6262
* @param length size_t
63+
* @param mask bool add dummy mask to the frame (needed for web browser)
64+
* @param fin bool can be used to send data in more then one frame (set fin on the last frame)
65+
* @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!)
6366
*/
64-
void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin) {
67+
void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) {
6568

6669
if(!client->tcp.connected()) {
6770
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num);
@@ -74,73 +77,102 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
7477
}
7578

7679
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send massage frame -------\n", client->num);
77-
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u\n", client->num, fin, opcode, mask, length);
80+
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u headerToPayload: %u\n", client->num, fin, opcode, mask, length, headerToPayload);
7881

7982
if(opcode == WSop_text) {
80-
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, payload);
83+
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, (payload + (headerToPayload ? 14 : 0)));
8184
}
8285

8386
uint8_t maskKey[4] = { 0 };
84-
uint8_t buffer[16] = { 0 };
85-
uint8_t i = 0;
87+
uint8_t buffer[14] = { 0 };
88+
89+
uint8_t headerSize;
90+
uint8_t * headerPtr;
8691

87-
//create header
92+
// calculate header Size
93+
if(length < 126) {
94+
headerSize = 2;
95+
} else if(length < 0xFFFF) {
96+
headerSize = 4;
97+
} else {
98+
headerSize = 10;
99+
}
100+
101+
if(mask) {
102+
headerSize += 4;
103+
}
104+
105+
// set Header Pointer
106+
if(headerToPayload) {
107+
// calculate offset in payload
108+
headerPtr = (payload + (14 - headerSize));
109+
} else {
110+
headerPtr = &buffer[0];
111+
}
112+
113+
// create header
88114

89115
// byte 0
90-
buffer[i] = 0x00;
116+
*headerPtr = 0x00;
91117
if(fin) {
92-
buffer[i] |= bit(7); ///< set Fin
118+
*headerPtr |= bit(7); ///< set Fin
93119
}
94-
buffer[i++] |= opcode; ///< set opcode
120+
*headerPtr |= opcode; ///< set opcode
121+
headerPtr++;
95122

96123
// byte 1
97-
buffer[i] = 0x00;
124+
*headerPtr = 0x00;
98125
if(mask) {
99-
buffer[i] |= bit(7); ///< set mask
126+
*headerPtr |= bit(7); ///< set mask
100127
}
101128

102129
if(length < 126) {
103-
buffer[i++] |= length;
104-
130+
*headerPtr |= length; headerPtr++;
105131
} else if(length < 0xFFFF) {
106-
buffer[i++] |= 126;
107-
buffer[i++] = ((length >> 8) & 0xFF);
108-
buffer[i++] = (length & 0xFF);
132+
*headerPtr |= 126; headerPtr++;
133+
*headerPtr = ((length >> 8) & 0xFF); headerPtr++;
134+
*headerPtr = (length & 0xFF); headerPtr++;
109135
} else {
110136
// normaly we never get here (to less memory)
111-
buffer[i++] |= 127;
112-
buffer[i++] = 0x00;
113-
buffer[i++] = 0x00;
114-
buffer[i++] = 0x00;
115-
buffer[i++] = 0x00;
116-
buffer[i++] = ((length >> 24) & 0xFF);
117-
buffer[i++] = ((length >> 16) & 0xFF);
118-
buffer[i++] = ((length >> 8) & 0xFF);
119-
buffer[i++] = (length & 0xFF);
137+
*headerPtr |= 127; headerPtr++;
138+
*headerPtr = 0x00; headerPtr++;
139+
*headerPtr = 0x00; headerPtr++;
140+
*headerPtr = 0x00; headerPtr++;
141+
*headerPtr = 0x00; headerPtr++;
142+
*headerPtr = ((length >> 24) & 0xFF); headerPtr++;
143+
*headerPtr = ((length >> 16) & 0xFF); headerPtr++;
144+
*headerPtr = ((length >> 8) & 0xFF); headerPtr++;
145+
*headerPtr = (length & 0xFF); headerPtr++;
120146
}
121147

122148
if(mask) {
123149
// todo generate random mask key
124150
for(uint8_t x = 0; x < sizeof(maskKey); x++) {
125151
// maskKey[x] = random(0xFF);
126152
maskKey[x] = 0x00; // fake xor (0x00 0x00 0x00 0x00)
127-
buffer[i++] = maskKey[x];
153+
*headerPtr = maskKey[x]; headerPtr++;
128154
}
129155

130-
// todo encode XOR
156+
// todo encode XOR (note: using payload not working for static content from flash)
131157
//for(size_t x = 0; x < length; x++) {
132158
// payload[x] = (payload[x] ^ maskKey[x % 4]);
133159
//}
134160
}
135161

136-
// send header
137-
client->tcp.write(&buffer[0], i);
162+
if(headerToPayload) {
163+
// header has be added to payload
164+
// payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings
165+
// offset in payload is calculatetd 14 - headerSize
166+
client->tcp.write(&payload[(14 - headerSize)], (length + headerSize));
167+
} else {
168+
// send header
169+
client->tcp.write(&buffer[0], headerSize);
138170

139-
if(payload && length > 0) {
140-
// send payload
141-
client->tcp.write(&payload[0], length);
171+
if(payload && length > 0) {
172+
// send payload
173+
client->tcp.write(&payload[0], length);
174+
}
142175
}
143-
144176
}
145177

146178
/**

src/WebSockets.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class WebSockets {
106106
virtual void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length);
107107

108108
void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0);
109-
void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true);
109+
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);
110110

111111

112112
void handleWebsocket(WSclient_t * client);

src/WebSocketsClient.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,23 @@ void WebSocketsClient::onEvent(WebSocketClientEvent cbEvent) {
103103
* @param num uint8_t client id
104104
* @param payload uint8_t *
105105
* @param length size_t
106+
* @param headerToPayload bool (see sendFrame for more details)
106107
*/
107-
void WebSocketsClient::sendTXT(uint8_t * payload, size_t length) {
108+
void WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPayload) {
108109
if(length == 0) {
109110
length = strlen((const char *) payload);
110111
}
111112
if(clientIsConnected(&_client)) {
112-
sendFrame(&_client, WSop_text, payload, length, true);
113+
sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload);
113114
}
114115
}
115116

116117
void WebSocketsClient::sendTXT(const uint8_t * payload, size_t length) {
117118
sendTXT((uint8_t *) payload, length);
118119
}
119120

120-
void WebSocketsClient::sendTXT(char * payload, size_t length) {
121-
sendTXT((uint8_t *) payload, length);
121+
void WebSocketsClient::sendTXT(char * payload, size_t length, bool headerToPayload) {
122+
sendTXT((uint8_t *) payload, length, headerToPayload);
122123
}
123124

124125
void WebSocketsClient::sendTXT(const char * payload, size_t length) {
@@ -134,10 +135,11 @@ void WebSocketsClient::sendTXT(String payload) {
134135
* @param num uint8_t client id
135136
* @param payload uint8_t *
136137
* @param length size_t
138+
* @param headerToPayload bool (see sendFrame for more details)
137139
*/
138-
void WebSocketsClient::sendBIN(uint8_t * payload, size_t length) {
140+
void WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPayload) {
139141
if(clientIsConnected(&_client)) {
140-
sendFrame(&_client, WSop_binary, payload, length, true);
142+
sendFrame(&_client, WSop_binary, payload, length, true, true, headerToPayload);
141143
}
142144
}
143145

src/WebSocketsClient.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ class WebSocketsClient: private WebSockets {
5454

5555
void onEvent(WebSocketClientEvent cbEvent);
5656

57-
void sendTXT(uint8_t * payload, size_t length = 0);
57+
void sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false);
5858
void sendTXT(const uint8_t * payload, size_t length = 0);
59-
void sendTXT(char * payload, size_t length = 0);
59+
void sendTXT(char * payload, size_t length = 0, bool headerToPayload = false);
6060
void sendTXT(const char * payload, size_t length = 0);
6161
void sendTXT(String payload);
6262

63-
void sendBIN(uint8_t * payload, size_t length);
63+
void sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
6464
void sendBIN(const uint8_t * payload, size_t length);
6565

6666
void disconnect(void);

src/WebSocketsServer.cpp

+16-12
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) {
8585
* @param num uint8_t client id
8686
* @param payload uint8_t *
8787
* @param length size_t
88+
* @param headerToPayload bool (see sendFrame for more details)
8889
*/
89-
void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length) {
90+
void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
9091
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
9192
return;
9293
}
@@ -95,16 +96,16 @@ void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length) {
9596
}
9697
WSclient_t * client = &_clients[num];
9798
if(clientIsConnected(client)) {
98-
sendFrame(client, WSop_text, payload, length);
99+
sendFrame(client, WSop_text, payload, length, false, true, headerToPayload);
99100
}
100101
}
101102

102103
void WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) {
103104
sendTXT(num, (uint8_t *) payload, length);
104105
}
105106

106-
void WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length) {
107-
sendTXT(num, (uint8_t *) payload, length);
107+
void WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) {
108+
sendTXT(num, (uint8_t *) payload, length, headerToPayload);
108109
}
109110

110111
void WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) {
@@ -119,8 +120,9 @@ void WebSocketsServer::sendTXT(uint8_t num, String payload) {
119120
* send text data to client all
120121
* @param payload uint8_t *
121122
* @param length size_t
123+
* @param headerToPayload bool (see sendFrame for more details)
122124
*/
123-
void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length) {
125+
void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) {
124126
WSclient_t * client;
125127
if(length == 0) {
126128
length = strlen((const char *) payload);
@@ -129,7 +131,7 @@ void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length) {
129131
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
130132
client = &_clients[i];
131133
if(clientIsConnected(client)) {
132-
sendFrame(client, WSop_text, payload, length);
134+
sendFrame(client, WSop_text, payload, length, false, true, headerToPayload);
133135
}
134136
#ifdef ESP8266
135137
delay(0);
@@ -141,8 +143,8 @@ void WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) {
141143
broadcastTXT((uint8_t *) payload, length);
142144
}
143145

144-
void WebSocketsServer::broadcastTXT(char * payload, size_t length) {
145-
broadcastTXT((uint8_t *) payload, length);
146+
void WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) {
147+
broadcastTXT((uint8_t *) payload, length, headerToPayload);
146148
}
147149

148150
void WebSocketsServer::broadcastTXT(const char * payload, size_t length) {
@@ -158,14 +160,15 @@ void WebSocketsServer::broadcastTXT(String payload) {
158160
* @param num uint8_t client id
159161
* @param payload uint8_t *
160162
* @param length size_t
163+
* @param headerToPayload bool (see sendFrame for more details)
161164
*/
162-
void WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length) {
165+
void WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
163166
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
164167
return;
165168
}
166169
WSclient_t * client = &_clients[num];
167170
if(clientIsConnected(client)) {
168-
sendFrame(client, WSop_binary, payload, length);
171+
sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload);
169172
}
170173
}
171174

@@ -177,13 +180,14 @@ void WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t leng
177180
* send binary data to client all
178181
* @param payload uint8_t *
179182
* @param length size_t
183+
* @param headerToPayload bool (see sendFrame for more details)
180184
*/
181-
void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length) {
185+
void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) {
182186
WSclient_t * client;
183187
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
184188
client = &_clients[i];
185189
if(clientIsConnected(client)) {
186-
sendFrame(client, WSop_binary, payload, length);
190+
sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload);
187191
}
188192
#ifdef ESP8266
189193
delay(0);

src/WebSocketsServer.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,22 @@ class WebSocketsServer: private WebSockets {
5858
void onEvent(WebSocketServerEvent cbEvent);
5959

6060

61-
void sendTXT(uint8_t num, uint8_t * payload, size_t length = 0);
61+
void sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false);
6262
void sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0);
63-
void sendTXT(uint8_t num, char * payload, size_t length = 0);
63+
void sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false);
6464
void sendTXT(uint8_t num, const char * payload, size_t length = 0);
6565
void sendTXT(uint8_t num, String payload);
6666

67-
void broadcastTXT(uint8_t * payload, size_t length = 0);
67+
void broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false);
6868
void broadcastTXT(const uint8_t * payload, size_t length = 0);
69-
void broadcastTXT(char * payload, size_t length = 0);
69+
void broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false);
7070
void broadcastTXT(const char * payload, size_t length = 0);
7171
void broadcastTXT(String payload);
7272

73-
void sendBIN(uint8_t num, uint8_t * payload, size_t length);
73+
void sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false);
7474
void sendBIN(uint8_t num, const uint8_t * payload, size_t length);
7575

76-
void broadcastBIN(uint8_t * payload, size_t length);
76+
void broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
7777
void broadcastBIN(const uint8_t * payload, size_t length);
7878

7979
void disconnect(void);

0 commit comments

Comments
 (0)