Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
WebSocketClientSockJsAndStomp.ino

Example for connecting and maintining a connection with a SockJS+STOMP websocket connection.
In this example we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html).

Created on: 18.07.2017
Author: Martin Becker <mgbckr>, Contact: becker@informatik.uni-wuerzburg.de
*/

// PRE

#define USE_SERIAL Serial


// LIBRARIES

#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>


// SETTINGS

const char* wlan_ssid = "yourssid";
const char* wlan_password = "somepassword";

const char* ws_host = "the.host.net";
const int ws_port = 80;

// base URL for SockJS (websocket) connection
// The complete URL will look something like this(cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36):
// ws://<ws_host>:<ws_port>/<ws_baseurl>/<3digits>/<randomstring>/websocket
// For the default config of Spring's SockJS/STOMP support the default base URL is "/socketentry/".
const char* ws_baseurl = "/socketentry/"; // don't forget leading and trailing "/" !!!


// VARIABLES

WebSocketsClient webSocket;


// FUNCTIONS

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {

switch (type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[WSc] Disconnected!\n");
break;
case WStype_CONNECTED:
{
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
}
break;
case WStype_TEXT:
{
// #####################
// handle STOMP protocol
// #####################

String text = (char*) payload;

USE_SERIAL.printf("[WSc] get text: %s\n", payload);

if (payload[0] == 'h') {

USE_SERIAL.println("Heartbeat!");

} else if (payload[0] == 'o') {

// on open connection
char *msg = "[\"CONNECT\\naccept-version:1.1,1.0\\nheart-beat:10000,10000\\n\\n\\u0000\"]";
webSocket.sendTXT(msg);

} else if (text.startsWith("a[\"CONNECTED")) {

// subscribe to some channels

char *msg = "[\"SUBSCRIBE\\nid:sub-0\\ndestination:/user/queue/messages\\n\\n\\u0000\"]";
webSocket.sendTXT(msg);
delay(1000);

// and send a message

msg = "[\"SEND\\ndestination:/app/message\\n\\n{\\\"user\\\":\\\"esp\\\",\\\"message\\\":\\\"Hello!\\\"}\\u0000\"]";
webSocket.sendTXT(msg);
delay(1000);
}

break;
}
case WStype_BIN:
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
hexdump(payload, length);

// send data to server
// webSocket.sendBIN(payload, length);
break;
}

}

void setup() {

// setup serial

// USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);

// USE_SERIAL.setDebugOutput(true);

USE_SERIAL.println();


// connect to WiFi

USE_SERIAL.print("Logging into WLAN: "); Serial.print(wlan_ssid); Serial.print(" ...");
WiFi.mode(WIFI_STA);
WiFi.begin(wlan_ssid, wlan_password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
USE_SERIAL.print(".");
}
USE_SERIAL.println(" success.");
USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP());


// #####################
// create socket url according to SockJS protocol (cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36)
// #####################
String socketUrl = ws_baseurl;
socketUrl += random(0, 999);
socketUrl += "/";
socketUrl += random(0, 999999); // should be a random string, but this works (see )
socketUrl += "/websocket";

// connect to websocket
webSocket.begin(ws_host, ws_port, socketUrl);
webSocket.setExtraHeaders(); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config
// webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny
webSocket.onEvent(webSocketEvent);
}

void loop() {
webSocket.loop();
}
2 changes: 2 additions & 0 deletions src/WebSockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ typedef struct {
String base64Authorization; ///< Base64 encoded Auth request
String plainAuthorization; ///< Base64 encoded Auth request

String extraHeaders;

bool cHttpHeadersValid; ///< non-websocket http header validity indicator
size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count

Expand Down
18 changes: 16 additions & 2 deletions src/WebSocketsClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
WebSocketsClient::WebSocketsClient() {
_cbEvent = NULL;
_client.num = 0;
_client.extraHeaders = WEBSOCKETS_STRING("Origin: file://");
}

WebSocketsClient::~WebSocketsClient() {
Expand Down Expand Up @@ -274,6 +275,15 @@ void WebSocketsClient::setAuthorization(const char * auth) {
}
}

/**
* set extra headers for the http request;
* separate headers by "\r\n"
* @param extraHeaders const char * extraHeaders
*/
void WebSocketsClient::setExtraHeaders(const char * extraHeaders) {
_client.extraHeaders = extraHeaders;
}

//#################################################################################
//#################################################################################
//#################################################################################
Expand Down Expand Up @@ -479,8 +489,12 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n");
}

handshake += WEBSOCKETS_STRING("Origin: file://\r\n"
"User-Agent: arduino-WebSocket-Client\r\n");
// add extra headers; by default this includes "Origin: file://"
if (client->extraHeaders) {
handshake += client->extraHeaders + NEW_LINE;
}

handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n");

if(client->base64Authorization.length() > 0) {
handshake += WEBSOCKETS_STRING("Authorization: Basic ");
Expand Down
2 changes: 2 additions & 0 deletions src/WebSocketsClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class WebSocketsClient: private WebSockets {

void setAuthorization(const char * user, const char * password);
void setAuthorization(const char * auth);

void setExtraHeaders(const char * extraHeaders = NULL);

protected:
String _host;
Expand Down