mirror of
https://github.com/Links2004/arduinoWebSockets.git
synced 2025-07-14 15:56:30 +02:00
Merge pull request #90 from kenkus-futurice/master
Add socket.io client
This commit is contained in:
113
examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino
Normal file
113
examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* WebSocketClientSocketIO.ino
|
||||
*
|
||||
* Created on: 06.06.2016
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
#define MESSAGE_INTERVAL 30000
|
||||
#define HEARTBEAT_INTERVAL 25000
|
||||
|
||||
uint64_t messageTimestamp = 0;
|
||||
uint64_t heartbeatTimestamp = 0;
|
||||
bool isConnected = false;
|
||||
|
||||
void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) {
|
||||
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[WSc] Disconnected!\n");
|
||||
isConnected = false;
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
{
|
||||
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
|
||||
isConnected = true;
|
||||
|
||||
// send message to server when Connected
|
||||
// socket.io upgrade confirmation message (required)
|
||||
webSocket.sendTXT("5");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
||||
|
||||
// send message to server
|
||||
// webSocket.sendTXT("message here");
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght);
|
||||
hexdump(payload, lenght);
|
||||
|
||||
// send data to server
|
||||
// webSocket.sendBIN(payload, lenght);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
webSocket.begin("192.168.0.123", 81);
|
||||
//webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
|
||||
if(isConnected) {
|
||||
|
||||
uint64_t now = millis();
|
||||
|
||||
if(now - messageTimestamp > MESSAGE_INTERVAL) {
|
||||
messageTimestamp = now;
|
||||
// example socket.io message with type "messageType" and JSON payload
|
||||
webSocket.sendTXT("42[\"messageType\",{\"greeting\":\"hello\"}]");
|
||||
}
|
||||
if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
|
||||
heartbeatTimestamp = now;
|
||||
// socket.io heartbeat message
|
||||
webSocket.sendTXT("2");
|
||||
}
|
||||
}
|
||||
}
|
@ -296,7 +296,7 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) {
|
||||
}
|
||||
|
||||
if(size > WEBSOCKETS_MAX_HEADER_SIZE) {
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d to big!\n", client->num, size);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d too big!\n", client->num, size);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -364,7 +364,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) {
|
||||
}
|
||||
|
||||
if(buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) {
|
||||
// really to big!
|
||||
// really too big!
|
||||
header->payloadLen = 0xFFFFFFFF;
|
||||
} else {
|
||||
header->payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7];
|
||||
@ -377,7 +377,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) {
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, header->mask, header->payloadLen);
|
||||
|
||||
if(header->payloadLen > WEBSOCKETS_MAX_DATA_SIZE) {
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, header->payloadLen);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload too big! (%u)\n", client->num, header->payloadLen);
|
||||
clientDisconnect(client, 1009);
|
||||
return;
|
||||
}
|
||||
@ -596,4 +596,3 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -161,6 +161,8 @@ typedef struct {
|
||||
|
||||
WEBSOCKETS_NETWORK_CLASS * tcp;
|
||||
|
||||
bool isSocketIO; ///< client for socket.io server
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
bool isSSL; ///< run in ssl mode
|
||||
WiFiClientSecure * ssl;
|
||||
@ -172,6 +174,7 @@ typedef struct {
|
||||
bool cIsUpgrade; ///< Connection == Upgrade
|
||||
bool cIsWebsocket; ///< Upgrade == websocket
|
||||
|
||||
String cSessionId; ///< client Set-Cookie (session id)
|
||||
String cKey; ///< client Sec-WebSocket-Key
|
||||
String cAccept; ///< client Sec-WebSocket-Accept
|
||||
String cProtocol; ///< client Sec-WebSocket-Protocol
|
||||
|
@ -91,6 +91,14 @@ void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String f
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebSocketsClient::beginSocketIO(const char *host, uint16_t port, const char * url, const char * protocol) {
|
||||
begin(host, port, url, protocol);
|
||||
_client.isSocketIO = true;
|
||||
}
|
||||
|
||||
void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, String protocol) {
|
||||
beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str());
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
/**
|
||||
@ -393,22 +401,37 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
|
||||
unsigned long start = micros();
|
||||
#endif
|
||||
|
||||
String handshake = "GET " + client->cUrl + " HTTP/1.1\r\n"
|
||||
"Host: " + _host + ":" + _port + "\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Origin: file://\r\n"
|
||||
"User-Agent: arduino-WebSocket-Client\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"Sec-WebSocket-Key: " + client->cKey + "\r\n";
|
||||
String transport;
|
||||
String handshake;
|
||||
if(!client->isSocketIO || (client->isSocketIO && client->cSessionId.length() > 0)) {
|
||||
if(client->isSocketIO) {
|
||||
transport = "&transport=websocket&sid=" + client->cSessionId;
|
||||
}
|
||||
handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n"
|
||||
"Host: " + _host + ":" + _port + "\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Origin: file://\r\n"
|
||||
"User-Agent: arduino-WebSocket-Client\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"Sec-WebSocket-Key: " + client->cKey + "\r\n";
|
||||
|
||||
if(client->cProtocol.length() > 0) {
|
||||
handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n";
|
||||
if(client->cProtocol.length() > 0) {
|
||||
handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n";
|
||||
}
|
||||
|
||||
if(client->cExtensions.length() > 0) {
|
||||
handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
handshake = "GET " + client->cUrl + "&transport=polling HTTP/1.1\r\n"
|
||||
"Connection: keep-alive\r\n";
|
||||
}
|
||||
|
||||
if(client->cExtensions.length() > 0) {
|
||||
handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n";
|
||||
}
|
||||
handshake += "Host: " + _host + ":" + _port + "\r\n"
|
||||
"Origin: file://\r\n"
|
||||
"User-Agent: arduino-WebSocket-Client\r\n";
|
||||
|
||||
if(client->base64Authorization.length() > 0) {
|
||||
handshake += "Authorization: Basic " + client->base64Authorization + "\r\n";
|
||||
@ -465,6 +488,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
client->cExtensions = headerValue;
|
||||
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) {
|
||||
client->cVersion = headerValue.toInt();
|
||||
} else if(headerName.equalsIgnoreCase("Set-Cookie")) {
|
||||
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1);
|
||||
}
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
|
||||
@ -490,6 +515,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cProtocol: %s\n", client->cProtocol.c_str());
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cExtensions: %s\n", client->cExtensions.c_str());
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion);
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str());
|
||||
|
||||
bool ok = (client->cIsUpgrade && client->cIsWebsocket);
|
||||
|
||||
@ -498,6 +524,10 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
case 101: ///< Switching Protocols
|
||||
|
||||
break;
|
||||
case 200:
|
||||
if(client->isSocketIO) {
|
||||
break;
|
||||
}
|
||||
case 403: ///< Forbidden
|
||||
// todo handle login
|
||||
default: ///< Server dont unterstand requrst
|
||||
@ -530,6 +560,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
|
||||
runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length());
|
||||
|
||||
} else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) {
|
||||
sendHeader(client);
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
|
||||
client->tcp->write("This is a webSocket client!");
|
||||
|
@ -48,6 +48,9 @@ class WebSocketsClient: private WebSockets {
|
||||
void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino");
|
||||
#endif
|
||||
|
||||
void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
|
||||
void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
void loop(void);
|
||||
#else
|
||||
|
Reference in New Issue
Block a user