-
Notifications
You must be signed in to change notification settings - Fork 90
/
Copy pathSocketIoClient.cpp
132 lines (117 loc) · 3.53 KB
/
SocketIoClient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <SocketIoClient.h>
const String getEventName(const String msg) {
return msg.substring(4, msg.indexOf("\"",4));
}
const String getEventPayload(const String msg) {
String result = msg.substring(msg.indexOf("\"",4)+2,msg.length()-1);
if(result.startsWith("\"")) {
result.remove(0,1);
}
if(result.endsWith("\"")) {
result.remove(result.length()-1);
}
return result;
}
static void hexdump(const uint32_t* src, size_t count) {
for (size_t i = 0; i < count; ++i) {
Serial.printf("%08x ", *src);
++src;
if ((i + 1) % 4 == 0) {
Serial.printf("\n");
}
}
}
void SocketIoClient::webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
String msg;
switch(type) {
case WStype_DISCONNECTED:
SOCKETIOCLIENT_DEBUG("[SIoC] Disconnected!\n");
break;
case WStype_CONNECTED:
SOCKETIOCLIENT_DEBUG("[SIoC] Connected to url: %s\n", payload);
break;
case WStype_TEXT:
msg = String((char*)payload);
if(msg.startsWith("42")) {
trigger(getEventName(msg).c_str(), getEventPayload(msg).c_str(), getEventPayload(msg).length());
} else if(msg.startsWith("2")) {
_webSocket.sendTXT("3");
} else if(msg.startsWith("40")) {
trigger("connect", NULL, 0);
} else if(msg.startsWith("41")) {
trigger("disconnect", NULL, 0);
}
break;
case WStype_BIN:
SOCKETIOCLIENT_DEBUG("[SIoC] get binary length: %u\n", length);
hexdump((uint32_t*) payload, length);
break;
}
}
void SocketIoClient::beginSSL(const char* host, const int port, const char* url, const char* fingerprint) {
_webSocket.beginSSL(host, port, url, fingerprint);
initialize();
}
void SocketIoClient::begin(const char* host, const int port, const char* url) {
_webSocket.begin(host, port, url);
initialize();
}
void SocketIoClient::initialize() {
_webSocket.onEvent(std::bind(&SocketIoClient::webSocketEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_lastPing = millis();
}
void SocketIoClient::loop() {
_webSocket.loop();
for(auto packet=_packets.begin(); packet != _packets.end();) {
if(_webSocket.sendTXT(*packet)) {
SOCKETIOCLIENT_DEBUG("[SIoC] packet \"%s\" emitted\n", packet->c_str());
packet = _packets.erase(packet);
} else {
++packet;
}
}
if(millis() - _lastPing > PING_INTERVAL) {
_webSocket.sendTXT("2");
_lastPing = millis();
}
}
void SocketIoClient::on(const char* event, std::function<void (const char * payload, size_t length)> func) {
_events[event] = func;
}
void SocketIoClient::emit(const char* event, const char * payload) {
String msg = String("42[\"");
msg += event;
msg += "\"";
if(payload) {
msg += ",";
msg += payload;
}
msg += "]";
SOCKETIOCLIENT_DEBUG("[SIoC] add packet %s\n", msg.c_str());
_packets.push_back(msg);
}
void SocketIoClient::remove(const char* event) {
auto e = _events.find(event);
if(e != _events.end()) {
_events.erase(e);
} else {
SOCKETIOCLIENT_DEBUG("[SIoC] event %s not found, can not be removed", event);
}
}
void SocketIoClient::trigger(const char* event, const char * payload, size_t length) {
auto e = _events.find(event);
if(e != _events.end()) {
SOCKETIOCLIENT_DEBUG("[SIoC] trigger event %s\n", event);
e->second(payload, length);
} else {
SOCKETIOCLIENT_DEBUG("[SIoC] event %s not found. %d events available\n", event, _events.size());
}
}
void SocketIoClient::disconnect()
{
_webSocket.disconnect();
trigger("disconnect", NULL, 0);
}
void SocketIoClient::setAuthorization(const char * user, const char * password) {
_webSocket.setAuthorization(user, password);
}