SocketIO updated for K64F usage

Fork of SocketIO by Doug Anson

Committer:
ansond
Date:
Mon Jul 08 02:43:43 2013 +0000
Revision:
2:2979735cb379
Parent:
0:5e68215d973a
Child:
3:529ce2bcfe77
header update

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 0:5e68215d973a 70 char buffer[256];
ansond 0:5e68215d973a 71 char *json = this->prepareSocketIOJSONMessage(name,args,buffer);
ansond 0:5e68215d973a 72
ansond 0:5e68215d973a 73 // send the message
ansond 0:5e68215d973a 74 bytesSent = this->ws->send(json);
ansond 0:5e68215d973a 75 }
ansond 0:5e68215d973a 76
ansond 0:5e68215d973a 77 return bytesSent;
ansond 0:5e68215d973a 78 }
ansond 0:5e68215d973a 79
ansond 0:5e68215d973a 80 // read a message from the SocketIO server
ansond 0:5e68215d973a 81 bool SocketIO::read(char * message) {
ansond 0:5e68215d973a 82 bool didRead = false;
ansond 0:5e68215d973a 83
ansond 0:5e68215d973a 84 // only read if we are connected
ansond 0:5e68215d973a 85 if (this->is_connected() == true && message != NULL) {
ansond 0:5e68215d973a 86 // attempt a read
ansond 0:5e68215d973a 87 didRead = this->ws->read(message);
ansond 0:5e68215d973a 88 }
ansond 0:5e68215d973a 89
ansond 0:5e68215d973a 90 // return our status
ansond 0:5e68215d973a 91 return didRead;
ansond 0:5e68215d973a 92 }
ansond 0:5e68215d973a 93
ansond 0:5e68215d973a 94 // Are we connected?
ansond 0:5e68215d973a 95 bool SocketIO::is_connected() {
ansond 0:5e68215d973a 96 bool isConnected = false;
ansond 0:5e68215d973a 97
ansond 0:5e68215d973a 98 // if we have an endpoint - get its connection status
ansond 0:5e68215d973a 99 if (this->ws != NULL) isConnected = this->ws->is_connected();
ansond 0:5e68215d973a 100
ansond 0:5e68215d973a 101 return isConnected;
ansond 0:5e68215d973a 102 }
ansond 0:5e68215d973a 103
ansond 0:5e68215d973a 104 // Private Methods
ansond 0:5e68215d973a 105
ansond 0:5e68215d973a 106 // prepare a SocketIO compatible JSON packet
ansond 0:5e68215d973a 107 char *SocketIO::prepareSocketIOJSONMessage(char *name, char *args, char *buffer) {
ansond 0:5e68215d973a 108 sprintf(buffer,"5:::{\"name\": \"%s\", \"args\": \"%s\"}",name, args);
ansond 0:5e68215d973a 109 return buffer;
ansond 0:5e68215d973a 110 }
ansond 0:5e68215d973a 111
ansond 0:5e68215d973a 112 // prepare the session URL
ansond 0:5e68215d973a 113 void SocketIO::prepareSessionURL() {
ansond 0:5e68215d973a 114 // allocate the buffer
ansond 0:5e68215d973a 115 this->url_session = new char[256];
ansond 0:5e68215d973a 116
ansond 0:5e68215d973a 117 // fill the buffer
ansond 0:5e68215d973a 118 sprintf(this->url_session,"ws://%s/%s/%s",this->url,this->ws_channel,this->session_key);
ansond 0:5e68215d973a 119 }
ansond 0:5e68215d973a 120
ansond 0:5e68215d973a 121 // attempt a connection via websockets
ansond 0:5e68215d973a 122 bool SocketIO::attemptWebSocketConnect() {
ansond 0:5e68215d973a 123 // attempt connect
ansond 0:5e68215d973a 124 int status = 0;
ansond 0:5e68215d973a 125 for(int i=0;i<10;++i) {
ansond 0:5e68215d973a 126 status = this->ws->connect();
ansond 0:5e68215d973a 127 if (status != 0) i = 10;
ansond 0:5e68215d973a 128 }
ansond 0:5e68215d973a 129
ansond 0:5e68215d973a 130 // set the socket.io connect command
ansond 0:5e68215d973a 131 if (this->ws->is_connected()) this->ws->send("1::");
ansond 0:5e68215d973a 132
ansond 0:5e68215d973a 133 // return connection status
ansond 0:5e68215d973a 134 return this->is_connected();
ansond 0:5e68215d973a 135 }
ansond 0:5e68215d973a 136
ansond 0:5e68215d973a 137 // prepare the session key URL
ansond 0:5e68215d973a 138 void SocketIO::prepareSessionKeyURL(char *myurl, int myversion) {
ansond 0:5e68215d973a 139 // save the base URL
ansond 0:5e68215d973a 140 this->url = myurl;
ansond 0:5e68215d973a 141
ansond 0:5e68215d973a 142 // set our version
ansond 0:5e68215d973a 143 this->version = myversion;
ansond 0:5e68215d973a 144
ansond 0:5e68215d973a 145 // build out the session key URL
ansond 0:5e68215d973a 146 this->url_session_key = new char[256];
ansond 0:5e68215d973a 147 time_t seconds = time(NULL);
ansond 0:5e68215d973a 148 sprintf(this->url_session_key,"http://%s/socket.io/%d/?t=%d",this->url,this->version,seconds);
ansond 0:5e68215d973a 149
ansond 0:5e68215d973a 150 // setup the session key and channel buffers
ansond 0:5e68215d973a 151 this->session_key = new char[128];
ansond 0:5e68215d973a 152 this->ws_channel = new char[128];
ansond 0:5e68215d973a 153 }
ansond 0:5e68215d973a 154
ansond 0:5e68215d973a 155 // parse the socket.io session key
ansond 0:5e68215d973a 156 void SocketIO::parseSessionKey(char *response, char *sessionkey, char *channel) {
ansond 0:5e68215d973a 157 int val1 = 0;
ansond 0:5e68215d973a 158 int val2 = 0;
ansond 0:5e68215d973a 159
ansond 0:5e68215d973a 160 // convert ":" to " "
ansond 0:5e68215d973a 161 for(int i=0;i<strlen(response);++i) if (response[i] == ':') response[i] = ' ';
ansond 0:5e68215d973a 162
ansond 0:5e68215d973a 163 // format: Session_ID YY ZZ CHANNEL
ansond 0:5e68215d973a 164 char t_sessionkey[128];
ansond 0:5e68215d973a 165 sscanf(response,"%s %d %d %s",t_sessionkey,&val1,&val2,channel);
ansond 0:5e68215d973a 166
ansond 0:5e68215d973a 167 // create
ansond 0:5e68215d973a 168 sprintf(sessionkey,"%s/%s",channel,t_sessionkey);
ansond 0:5e68215d973a 169 }
ansond 0:5e68215d973a 170
ansond 0:5e68215d973a 171 // acquire the session key for our session
ansond 0:5e68215d973a 172 bool SocketIO::acquireSessionKey() {
ansond 0:5e68215d973a 173 bool haveKey = false;
ansond 0:5e68215d973a 174 HTTPClient http;
ansond 0:5e68215d973a 175 char response[513];
ansond 0:5e68215d973a 176
ansond 0:5e68215d973a 177 // make sure we have buffers
ansond 0:5e68215d973a 178 if (this->session_key != NULL && this->ws_channel != NULL) {
ansond 0:5e68215d973a 179 // request our session key
ansond 0:5e68215d973a 180 int nread = http.get(this->url_session_key,response,512);
ansond 0:5e68215d973a 181
ansond 0:5e68215d973a 182 // parse the session key
ansond 0:5e68215d973a 183 if (!nread)
ansond 0:5e68215d973a 184 // parse into the session key
ansond 0:5e68215d973a 185 this->parseSessionKey(response,this->session_key,this->ws_channel);
ansond 0:5e68215d973a 186
ansond 0:5e68215d973a 187 // update our status
ansond 0:5e68215d973a 188 if (strlen(this->session_key) > 0) haveKey = true;
ansond 0:5e68215d973a 189 }
ansond 0:5e68215d973a 190
ansond 0:5e68215d973a 191 // return status
ansond 0:5e68215d973a 192 return haveKey;
ansond 0:5e68215d973a 193 }