Skip to content

Commit 529a86c

Browse files
authored
Merge pull request #90 from kenkus-futurice/master
Add socket.io client
2 parents 958ab08 + bf3cfa6 commit 529a86c

File tree

5 files changed

+168
-18
lines changed

5 files changed

+168
-18
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* WebSocketClientSocketIO.ino
3+
*
4+
* Created on: 06.06.2016
5+
*
6+
*/
7+
8+
#include <Arduino.h>
9+
10+
#include <ESP8266WiFi.h>
11+
#include <ESP8266WiFiMulti.h>
12+
13+
#include <WebSocketsClient.h>
14+
15+
#include <Hash.h>
16+
17+
ESP8266WiFiMulti WiFiMulti;
18+
WebSocketsClient webSocket;
19+
20+
21+
#define USE_SERIAL Serial1
22+
23+
#define MESSAGE_INTERVAL 30000
24+
#define HEARTBEAT_INTERVAL 25000
25+
26+
uint64_t messageTimestamp = 0;
27+
uint64_t heartbeatTimestamp = 0;
28+
bool isConnected = false;
29+
30+
void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) {
31+
32+
33+
switch(type) {
34+
case WStype_DISCONNECTED:
35+
USE_SERIAL.printf("[WSc] Disconnected!\n");
36+
isConnected = false;
37+
break;
38+
case WStype_CONNECTED:
39+
{
40+
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
41+
isConnected = true;
42+
43+
// send message to server when Connected
44+
// socket.io upgrade confirmation message (required)
45+
webSocket.sendTXT("5");
46+
}
47+
break;
48+
case WStype_TEXT:
49+
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
50+
51+
// send message to server
52+
// webSocket.sendTXT("message here");
53+
break;
54+
case WStype_BIN:
55+
USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght);
56+
hexdump(payload, lenght);
57+
58+
// send data to server
59+
// webSocket.sendBIN(payload, lenght);
60+
break;
61+
}
62+
63+
}
64+
65+
void setup() {
66+
// USE_SERIAL.begin(921600);
67+
USE_SERIAL.begin(115200);
68+
69+
//Serial.setDebugOutput(true);
70+
USE_SERIAL.setDebugOutput(true);
71+
72+
USE_SERIAL.println();
73+
USE_SERIAL.println();
74+
USE_SERIAL.println();
75+
76+
for(uint8_t t = 4; t > 0; t--) {
77+
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
78+
USE_SERIAL.flush();
79+
delay(1000);
80+
}
81+
82+
WiFiMulti.addAP("SSID", "passpasspass");
83+
84+
//WiFi.disconnect();
85+
while(WiFiMulti.run() != WL_CONNECTED) {
86+
delay(100);
87+
}
88+
89+
webSocket.begin("192.168.0.123", 81);
90+
//webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization
91+
webSocket.onEvent(webSocketEvent);
92+
93+
}
94+
95+
void loop() {
96+
webSocket.loop();
97+
98+
if(isConnected) {
99+
100+
uint64_t now = millis();
101+
102+
if(now - messageTimestamp > MESSAGE_INTERVAL) {
103+
messageTimestamp = now;
104+
// example socket.io message with type "messageType" and JSON payload
105+
webSocket.sendTXT("42[\"messageType\",{\"greeting\":\"hello\"}]");
106+
}
107+
if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
108+
heartbeatTimestamp = now;
109+
// socket.io heartbeat message
110+
webSocket.sendTXT("2");
111+
}
112+
}
113+
}

src/WebSockets.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) {
296296
}
297297

298298
if(size > WEBSOCKETS_MAX_HEADER_SIZE) {
299-
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d to big!\n", client->num, size);
299+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d too big!\n", client->num, size);
300300
return false;
301301
}
302302

@@ -364,7 +364,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) {
364364
}
365365

366366
if(buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) {
367-
// really to big!
367+
// really too big!
368368
header->payloadLen = 0xFFFFFFFF;
369369
} else {
370370
header->payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7];
@@ -377,7 +377,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) {
377377
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, header->mask, header->payloadLen);
378378

379379
if(header->payloadLen > WEBSOCKETS_MAX_DATA_SIZE) {
380-
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, header->payloadLen);
380+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload too big! (%u)\n", client->num, header->payloadLen);
381381
clientDisconnect(client, 1009);
382382
return;
383383
}
@@ -596,4 +596,3 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
596596
#endif
597597
return true;
598598
}
599-

src/WebSockets.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ typedef struct {
161161

162162
WEBSOCKETS_NETWORK_CLASS * tcp;
163163

164+
bool isSocketIO; ///< client for socket.io server
165+
164166
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
165167
bool isSSL; ///< run in ssl mode
166168
WiFiClientSecure * ssl;
@@ -172,6 +174,7 @@ typedef struct {
172174
bool cIsUpgrade; ///< Connection == Upgrade
173175
bool cIsWebsocket; ///< Upgrade == websocket
174176

177+
String cSessionId; ///< client Set-Cookie (session id)
175178
String cKey; ///< client Sec-WebSocket-Key
176179
String cAccept; ///< client Sec-WebSocket-Accept
177180
String cProtocol; ///< client Sec-WebSocket-Protocol

src/WebSocketsClient.cpp

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String f
9191
}
9292
#endif
9393

94+
void WebSocketsClient::beginSocketIO(const char *host, uint16_t port, const char * url, const char * protocol) {
95+
begin(host, port, url, protocol);
96+
_client.isSocketIO = true;
97+
}
98+
99+
void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, String protocol) {
100+
beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str());
101+
}
94102

95103
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
96104
/**
@@ -393,23 +401,38 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
393401
unsigned long start = micros();
394402
#endif
395403

396-
String handshake = "GET " + client->cUrl + " HTTP/1.1\r\n"
397-
"Host: " + _host + ":" + _port + "\r\n"
398-
"Connection: Upgrade\r\n"
399-
"Upgrade: websocket\r\n"
400-
"Origin: file://\r\n"
401-
"User-Agent: arduino-WebSocket-Client\r\n"
402-
"Sec-WebSocket-Version: 13\r\n"
403-
"Sec-WebSocket-Key: " + client->cKey + "\r\n";
404-
405-
if(client->cProtocol.length() > 0) {
406-
handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n";
407-
}
404+
String transport;
405+
String handshake;
406+
if(!client->isSocketIO || (client->isSocketIO && client->cSessionId.length() > 0)) {
407+
if(client->isSocketIO) {
408+
transport = "&transport=websocket&sid=" + client->cSessionId;
409+
}
410+
handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n"
411+
"Host: " + _host + ":" + _port + "\r\n"
412+
"Connection: Upgrade\r\n"
413+
"Upgrade: websocket\r\n"
414+
"Origin: file://\r\n"
415+
"User-Agent: arduino-WebSocket-Client\r\n"
416+
"Sec-WebSocket-Version: 13\r\n"
417+
"Sec-WebSocket-Key: " + client->cKey + "\r\n";
418+
419+
if(client->cProtocol.length() > 0) {
420+
handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n";
421+
}
422+
423+
if(client->cExtensions.length() > 0) {
424+
handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n";
425+
}
408426

409-
if(client->cExtensions.length() > 0) {
410-
handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n";
427+
} else {
428+
handshake = "GET " + client->cUrl + "&transport=polling HTTP/1.1\r\n"
429+
"Connection: keep-alive\r\n";
411430
}
412431

432+
handshake += "Host: " + _host + ":" + _port + "\r\n"
433+
"Origin: file://\r\n"
434+
"User-Agent: arduino-WebSocket-Client\r\n";
435+
413436
if(client->base64Authorization.length() > 0) {
414437
handshake += "Authorization: Basic " + client->base64Authorization + "\r\n";
415438
}
@@ -465,6 +488,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
465488
client->cExtensions = headerValue;
466489
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) {
467490
client->cVersion = headerValue.toInt();
491+
} else if(headerName.equalsIgnoreCase("Set-Cookie")) {
492+
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1);
468493
}
469494
} else {
470495
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
@@ -490,6 +515,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
490515
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cProtocol: %s\n", client->cProtocol.c_str());
491516
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cExtensions: %s\n", client->cExtensions.c_str());
492517
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion);
518+
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str());
493519

494520
bool ok = (client->cIsUpgrade && client->cIsWebsocket);
495521

@@ -498,6 +524,10 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
498524
case 101: ///< Switching Protocols
499525

500526
break;
527+
case 200:
528+
if(client->isSocketIO) {
529+
break;
530+
}
501531
case 403: ///< Forbidden
502532
// todo handle login
503533
default: ///< Server dont unterstand requrst
@@ -530,6 +560,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
530560

531561
runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length());
532562

563+
} else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) {
564+
sendHeader(client);
533565
} else {
534566
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
535567
client->tcp->write("This is a webSocket client!");

src/WebSocketsClient.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ class WebSocketsClient: private WebSockets {
4848
void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino");
4949
#endif
5050

51+
void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
52+
void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
53+
5154
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
5255
void loop(void);
5356
#else

0 commit comments

Comments
 (0)