SocketIO updated for K64F usage
Fork of SocketIO by
SocketIO.cpp@4:ad06c58c7cf4, 2013-07-08 (annotated)
- Committer:
- ansond
- Date:
- Mon Jul 08 03:35:29 2013 +0000
- Revision:
- 4:ad06c58c7cf4
- Parent:
- 3:529ce2bcfe77
- Child:
- 5:912301390ce1
updates
Who changed what in which revision?
User | Revision | Line number | New 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 | 3:529ce2bcfe77 | 73 | // send a heartbeat |
ansond | 3:529ce2bcfe77 | 74 | this->ws->send("2::"); |
ansond | 3:529ce2bcfe77 | 75 | |
ansond | 0:5e68215d973a | 76 | // send the message |
ansond | 0:5e68215d973a | 77 | 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 | 0:5e68215d973a | 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 | 4:ad06c58c7cf4 | 121 | sprintf(this->url_session,"ws://%s/%s",this->url,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 | 4:ad06c58c7cf4 | 168 | sscanf(response,"%s %d %d %s",t_sessionkey,&val1,&val2,this->channel); |
ansond | 0:5e68215d973a | 169 | |
ansond | 0:5e68215d973a | 170 | // create |
ansond | 4:ad06c58c7cf4 | 171 | sprintf(sessionkey,"%s/%s",this->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 | 0:5e68215d973a | 178 | char response[513]; |
ansond | 0:5e68215d973a | 179 | |
ansond | 0:5e68215d973a | 180 | // make sure we have buffers |
ansond | 0:5e68215d973a | 181 | if (this->session_key != NULL && this->ws_channel != NULL) { |
ansond | 0:5e68215d973a | 182 | // request our session key |
ansond | 0:5e68215d973a | 183 | int nread = http.get(this->url_session_key,response,512); |
ansond | 0:5e68215d973a | 184 | |
ansond | 0:5e68215d973a | 185 | // parse the session key |
ansond | 0:5e68215d973a | 186 | if (!nread) |
ansond | 0:5e68215d973a | 187 | // parse into the session key |
ansond | 0:5e68215d973a | 188 | this->parseSessionKey(response,this->session_key,this->ws_channel); |
ansond | 0:5e68215d973a | 189 | |
ansond | 0:5e68215d973a | 190 | // update our status |
ansond | 0:5e68215d973a | 191 | if (strlen(this->session_key) > 0) haveKey = true; |
ansond | 0:5e68215d973a | 192 | } |
ansond | 0:5e68215d973a | 193 | |
ansond | 0:5e68215d973a | 194 | // return status |
ansond | 0:5e68215d973a | 195 | return haveKey; |
ansond | 0:5e68215d973a | 196 | } |