SocketIO updated for K64F usage

Fork of SocketIO by Doug Anson

Committer:
ansond
Date:
Thu Oct 09 16:13:12 2014 +0000
Revision:
13:1b8ff174aea6
Parent:
12:8fe60d9ca3bf
updates for K64F

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:5e68215d973a 1 #include "SocketIO.h"
ansond 0:5e68215d973a 2
ansond 0:5e68215d973a 3 // constructor
ansond 0:5e68215d973a 4 SocketIO::SocketIO(char * myurl) {
ansond 0:5e68215d973a 5 // prepare the sessionkey URL
ansond 0:5e68215d973a 6 this->prepareSessionKeyURL(myurl, DEFAULT_VERSION);
ansond 0:5e68215d973a 7 }
ansond 0:5e68215d973a 8
ansond 0:5e68215d973a 9 // constructor
ansond 0:5e68215d973a 10 SocketIO::SocketIO(char * myurl, int myversion) {
ansond 0:5e68215d973a 11 // prepare the sessionkey URL
ansond 0:5e68215d973a 12 this->prepareSessionKeyURL(myurl, myversion);
ansond 0:5e68215d973a 13 }
ansond 0:5e68215d973a 14
ansond 0:5e68215d973a 15 // connect to the SocketIO server
ansond 0:5e68215d973a 16 bool SocketIO::connect() {
ansond 0:5e68215d973a 17 bool connected = this->is_connected();
ansond 0:5e68215d973a 18
ansond 0:5e68215d973a 19 // make sure we are not already connected
ansond 0:5e68215d973a 20 if (connected == false) {
ansond 0:5e68215d973a 21 // first we must acquire the session key
ansond 0:5e68215d973a 22 bool connected = this->acquireSessionKey();
ansond 0:5e68215d973a 23
ansond 0:5e68215d973a 24 // next we must create a new URL to connect to with the session key
ansond 0:5e68215d973a 25 if (connected == true) {
ansond 0:5e68215d973a 26 // create our session URL
ansond 0:5e68215d973a 27 this->prepareSessionURL();
ansond 0:5e68215d973a 28
ansond 0:5e68215d973a 29 // allocate our websocket endpoint
ansond 0:5e68215d973a 30 this->ws = new Websocket(this->url_session);
ansond 0:5e68215d973a 31
ansond 0:5e68215d973a 32 // connect!
ansond 0:5e68215d973a 33 connected = this->attemptWebSocketConnect();
ansond 0:5e68215d973a 34 }
ansond 0:5e68215d973a 35 }
ansond 0:5e68215d973a 36
ansond 0:5e68215d973a 37 // return our connection status
ansond 0:5e68215d973a 38 return connected;
ansond 0:5e68215d973a 39 }
ansond 0:5e68215d973a 40
ansond 0:5e68215d973a 41 // gracefully disconnect from the SocketIO server
ansond 0:5e68215d973a 42 bool SocketIO::close() {
ansond 0:5e68215d973a 43 bool closed = false;
ansond 0:5e68215d973a 44
ansond 0:5e68215d973a 45 // if we are connected lets disconnect
ansond 0:5e68215d973a 46 if (this->ws != NULL) {
ansond 2:2979735cb379 47 this->ws->send("0::");
ansond 0:5e68215d973a 48 this->ws->close();
ansond 0:5e68215d973a 49 closed = this->ws->is_connected();
ansond 0:5e68215d973a 50 }
ansond 0:5e68215d973a 51
ansond 0:5e68215d973a 52 // now clean up memory
ansond 0:5e68215d973a 53 if (this->ws != NULL) delete this->ws;
ansond 0:5e68215d973a 54 if (this->url_session != NULL) delete this->url_session;
ansond 0:5e68215d973a 55 if (this->url_session_key != NULL) delete this->url_session_key;
ansond 0:5e68215d973a 56 if (this->session_key != NULL) delete this->session_key;
ansond 0:5e68215d973a 57 if (this->ws_channel != NULL) delete this->ws_channel;
ansond 0:5e68215d973a 58
ansond 0:5e68215d973a 59 // return our status
ansond 0:5e68215d973a 60 return closed;
ansond 0:5e68215d973a 61 }
ansond 0:5e68215d973a 62
ansond 0:5e68215d973a 63 // emit a message (broadcast) to the SocketIO server
ansond 0:5e68215d973a 64 int SocketIO::emit(char *name, char * args) {
ansond 0:5e68215d973a 65 int bytesSent = 0;
ansond 0:5e68215d973a 66
ansond 0:5e68215d973a 67 // only emit if we are connected
ansond 0:5e68215d973a 68 if (this->is_connected() == true) {
ansond 0:5e68215d973a 69 // prepare the JSON message for SocketIO
ansond 11:b32005b69b5c 70 char buffer[512];
ansond 0:5e68215d973a 71 char *json = this->prepareSocketIOJSONMessage(name,args,buffer);
ansond 0:5e68215d973a 72
ansond 3:529ce2bcfe77 73 // send a heartbeat
ansond 9:4f02450a402a 74 bytesSent = this->ws->send("2::");
ansond 3:529ce2bcfe77 75
ansond 0:5e68215d973a 76 // send the message
ansond 9:4f02450a402a 77 if (bytesSent > 0) bytesSent = this->ws->send(json);
ansond 0:5e68215d973a 78 }
ansond 0:5e68215d973a 79
ansond 0:5e68215d973a 80 return bytesSent;
ansond 0:5e68215d973a 81 }
ansond 0:5e68215d973a 82
ansond 0:5e68215d973a 83 // read a message from the SocketIO server
ansond 0:5e68215d973a 84 bool SocketIO::read(char * message) {
ansond 0:5e68215d973a 85 bool didRead = false;
ansond 0:5e68215d973a 86
ansond 0:5e68215d973a 87 // only read if we are connected
ansond 0:5e68215d973a 88 if (this->is_connected() == true && message != NULL) {
ansond 0:5e68215d973a 89 // attempt a read
ansond 0:5e68215d973a 90 didRead = this->ws->read(message);
ansond 0:5e68215d973a 91 }
ansond 0:5e68215d973a 92
ansond 0:5e68215d973a 93 // return our status
ansond 0:5e68215d973a 94 return didRead;
ansond 0:5e68215d973a 95 }
ansond 0:5e68215d973a 96
ansond 0:5e68215d973a 97 // Are we connected?
ansond 0:5e68215d973a 98 bool SocketIO::is_connected() {
ansond 0:5e68215d973a 99 bool isConnected = false;
ansond 0:5e68215d973a 100
ansond 0:5e68215d973a 101 // if we have an endpoint - get its connection status
ansond 0:5e68215d973a 102 if (this->ws != NULL) isConnected = this->ws->is_connected();
ansond 0:5e68215d973a 103
ansond 0:5e68215d973a 104 return isConnected;
ansond 0:5e68215d973a 105 }
ansond 0:5e68215d973a 106
ansond 0:5e68215d973a 107 // Private Methods
ansond 0:5e68215d973a 108
ansond 0:5e68215d973a 109 // prepare a SocketIO compatible JSON packet
ansond 0:5e68215d973a 110 char *SocketIO::prepareSocketIOJSONMessage(char *name, char *args, char *buffer) {
ansond 7:a9bafd7a45fc 111 sprintf(buffer,"5:::{\"name\": \"%s\", \"args\": %s}",name, args);
ansond 0:5e68215d973a 112 return buffer;
ansond 0:5e68215d973a 113 }
ansond 0:5e68215d973a 114
ansond 0:5e68215d973a 115 // prepare the session URL
ansond 0:5e68215d973a 116 void SocketIO::prepareSessionURL() {
ansond 0:5e68215d973a 117 // allocate the buffer
ansond 0:5e68215d973a 118 this->url_session = new char[256];
ansond 0:5e68215d973a 119
ansond 0:5e68215d973a 120 // fill the buffer
ansond 6:f71f8a61dc98 121 sprintf(this->url_session,"ws://%s/socket.io/%d/%s",this->url,this->version,this->session_key);
ansond 0:5e68215d973a 122 }
ansond 0:5e68215d973a 123
ansond 0:5e68215d973a 124 // attempt a connection via websockets
ansond 0:5e68215d973a 125 bool SocketIO::attemptWebSocketConnect() {
ansond 0:5e68215d973a 126 // attempt connect
ansond 0:5e68215d973a 127 int status = 0;
ansond 0:5e68215d973a 128 for(int i=0;i<10;++i) {
ansond 0:5e68215d973a 129 status = this->ws->connect();
ansond 0:5e68215d973a 130 if (status != 0) i = 10;
ansond 0:5e68215d973a 131 }
ansond 0:5e68215d973a 132
ansond 0:5e68215d973a 133 // set the socket.io connect command
ansond 0:5e68215d973a 134 if (this->ws->is_connected()) this->ws->send("1::");
ansond 0:5e68215d973a 135
ansond 0:5e68215d973a 136 // return connection status
ansond 0:5e68215d973a 137 return this->is_connected();
ansond 0:5e68215d973a 138 }
ansond 0:5e68215d973a 139
ansond 0:5e68215d973a 140 // prepare the session key URL
ansond 0:5e68215d973a 141 void SocketIO::prepareSessionKeyURL(char *myurl, int myversion) {
ansond 0:5e68215d973a 142 // save the base URL
ansond 0:5e68215d973a 143 this->url = myurl;
ansond 0:5e68215d973a 144
ansond 0:5e68215d973a 145 // set our version
ansond 0:5e68215d973a 146 this->version = myversion;
ansond 0:5e68215d973a 147
ansond 0:5e68215d973a 148 // build out the session key URL
ansond 0:5e68215d973a 149 this->url_session_key = new char[256];
ansond 0:5e68215d973a 150 time_t seconds = time(NULL);
ansond 0:5e68215d973a 151 sprintf(this->url_session_key,"http://%s/socket.io/%d/?t=%d",this->url,this->version,seconds);
ansond 0:5e68215d973a 152
ansond 0:5e68215d973a 153 // setup the session key and channel buffers
ansond 0:5e68215d973a 154 this->session_key = new char[128];
ansond 0:5e68215d973a 155 this->ws_channel = new char[128];
ansond 0:5e68215d973a 156 }
ansond 0:5e68215d973a 157
ansond 0:5e68215d973a 158 // parse the socket.io session key
ansond 0:5e68215d973a 159 void SocketIO::parseSessionKey(char *response, char *sessionkey, char *channel) {
ansond 0:5e68215d973a 160 int val1 = 0;
ansond 0:5e68215d973a 161 int val2 = 0;
ansond 0:5e68215d973a 162
ansond 0:5e68215d973a 163 // convert ":" to " "
ansond 0:5e68215d973a 164 for(int i=0;i<strlen(response);++i) if (response[i] == ':') response[i] = ' ';
ansond 0:5e68215d973a 165
ansond 0:5e68215d973a 166 // format: Session_ID YY ZZ CHANNEL
ansond 0:5e68215d973a 167 char t_sessionkey[128];
ansond 5:912301390ce1 168 sscanf(response,"%s %d %d %s",t_sessionkey,&val1,&val2,channel);
ansond 0:5e68215d973a 169
ansond 0:5e68215d973a 170 // create
ansond 5:912301390ce1 171 sprintf(sessionkey,"%s/%s",channel,t_sessionkey);
ansond 0:5e68215d973a 172 }
ansond 0:5e68215d973a 173
ansond 0:5e68215d973a 174 // acquire the session key for our session
ansond 0:5e68215d973a 175 bool SocketIO::acquireSessionKey() {
ansond 0:5e68215d973a 176 bool haveKey = false;
ansond 0:5e68215d973a 177 HTTPClient http;
ansond 13:1b8ff174aea6 178 char response[SOCKETIO_MESSAGE_LENGTH+1];
ansond 13:1b8ff174aea6 179 memset(response,0,SOCKETIO_MESSAGE_LENGTH+1);
ansond 0:5e68215d973a 180
ansond 0:5e68215d973a 181 // make sure we have buffers
ansond 0:5e68215d973a 182 if (this->session_key != NULL && this->ws_channel != NULL) {
ansond 0:5e68215d973a 183 // request our session key
ansond 13:1b8ff174aea6 184 int nread = http.get(this->url_session_key,response,SOCKETIO_MESSAGE_LENGTH);
ansond 0:5e68215d973a 185
ansond 0:5e68215d973a 186 // parse the session key
ansond 0:5e68215d973a 187 if (!nread)
ansond 0:5e68215d973a 188 // parse into the session key
ansond 0:5e68215d973a 189 this->parseSessionKey(response,this->session_key,this->ws_channel);
ansond 0:5e68215d973a 190
ansond 0:5e68215d973a 191 // update our status
ansond 0:5e68215d973a 192 if (strlen(this->session_key) > 0) haveKey = true;
ansond 0:5e68215d973a 193 }
ansond 0:5e68215d973a 194
ansond 0:5e68215d973a 195 // return status
ansond 0:5e68215d973a 196 return haveKey;
ansond 0:5e68215d973a 197 }