void StringTest::testReplaceInPlace() { std::string s("aabbccdd"); assert (replaceInPlace(s, std::string("aa"), std::string("xx")) == "xxbbccdd"); }
int main() { AutoPtr<XMLConfiguration> pConf(new XMLConfiguration("settings.xml")); // instantiating the XMLConfiguration and reading from setting.xml char buffer[2048]; memset(buffer, 0, sizeof buffer); int flags; int n; string payload; string out; int msg_cnt = 0; pthread_t fifoReadThread; //indivudual thread for fifo so it doesn't block other stuff int iret1 = pthread_create(&fifoReadThread, NULL, CreatePiSocketFifo, NULL); //variables to be set in xml config file // string signalr_service_url = pConf->getString("signalr_url"); string signalr_url_endpoint = pConf->getString("signalr_url_endpoint"); int signalr_service_port = pConf->getInt("signalr_port"); int timeout_seconds = pConf->getInt("timeout"); string api_endpoint_url = pConf->getString("api_endpoint_url"); // "" //pipe_from_main = pConf->getString("pipe_from_main"); //string pipe_from_socket = pConf->getString("pipe_from_socket"); //--------------------------------------// //cout << endl << "=============================================================" << endl; //cout << "api_endpoint_url -> " << api_endpoint_url << endl; //cout << "signalr_url_endpoint -> " << signalr_url_endpoint << endl; //cout << "signalr_service_port -> " << signalr_service_port << endl; //cout << "timeout_seconds -> " << timeout_seconds << endl; //cout << "api_endpoint_url -> " << api_endpoint_url << endl; //cout << "pipe_from_main -> " << pipe_from_main; //cout << endl << "=============================================================" << endl << endl; //cout << "Opening pipe: " << pipe_from_main << endl; //fd = open(pipe_from_main.c_str(), O_WRONLY); // open pipe as readonly //write(fd, "Hello World", sizeof("Hello World")); //close(fd); conn: //label for the goto's in the catches try{ time_t seconds_past_epoch = time(0); cout << "STARTING " << endl; char port[100]; char id[100]; snprintf(port, sizeof(port), "%d", signalr_service_port); // converting int variables to char[] snprintf(id, sizeof(id), "%ld", (seconds_past_epoch * 1000)); // converting int variables to char[] string my_mac = getMACC(); //Get the mac address //compose the URI for getting the token URI uri("http://" + signalr_service_url + ":" + port + "/" + signalr_url_endpoint + "/negotiate?_" + id + "&UID=" + my_mac); HTTPClientSession session(uri.getHost(), uri.getPort()); // instantiating a client session //if there is a network problem between Pi and SignalR everything will break and the catch will point back to the goto label //we set this in order to a lower minimise the retry period thus the downtime session.setTimeout(timeout_seconds * 1e+6); // time in microseconds; string path(uri.getPathAndQuery()); // send the request HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); session.sendRequest(req); StringTokenizer tokenizer(session.socket().address().toString(), ":", StringTokenizer::TOK_TRIM); // get the request originating address:ip from the session socket initiated by HTPP; tokenize it for IP extraction //string my_mac = getMAC((tokenizer[0]).c_str()); // call IP to MAC converter // get response HTTPResponse res; istream& is = session.receiveResponse(res); // stream the request cout << res.getStatus() << " " << res.getReason() << endl; // get the status code of the transaction // convert the istream to sting for further processing istreambuf_iterator<char> eos; string s(istreambuf_iterator<char>(is), eos); const char * cc = s.c_str(); // instantiate a rapidjson document and fill it up with the response of the negotiation request rapidjson::Document document; document.Parse<0>(cc); string token = document["ConnectionToken"].GetString(); // parse the response and get the connectionToken //============================================= //connect to signarR using the connectionToken got previously HTTPClientSession cs(signalr_service_url, signalr_service_port); // instantiate simple webclient string what = "/" + signalr_url_endpoint + "/connect?transport=webSockets&connectionToken=" + urlencode(token) + "&UID=" + my_mac + "&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&tid=10"; // compose the request string HTTPRequest request(HTTPRequest::HTTP_GET, what, "HTTP/1.1"); // the protocol MUST be HTTP/1.1, as described in RFC6455; else the UPGRADE to websocket request will fail request.set("Host", signalr_service_url); // specify the Host header to be sent HTTPResponse response; // instantiate a http response cout << response.getStatus() << " " << response.getReason() << endl; WebSocket * ws = new WebSocket(cs, request, response); // instantiate a WebSocket transaction to the 'cs' session, sending the 'request' and storing the 'response' //sample of a message to be sent payload = "{\"H\":\"myhub\",\"M\":\"Send\",\"A\":[\"" + my_mac + "\",\"invoked from " + replaceInPlace(my_mac, std::string(":"), std::string("-")) + " client\"],\"I\":0}"; // cout << endl << payload << endl ; ws->sendFrame(payload.data(), payload.size(), WebSocket::FRAME_TEXT); // send the message to signalR using the payload and setting the type of frame to be sent as FRAME_TEXT flags = 1; // starting the receiving loop while( (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE ) // while websocket session open { n = ws->receiveFrame(buffer, sizeof(buffer), flags); // n is the received frame // flags store the response flags of the frame // 129 = single frame response // 1 = start of multi-frame response // 0 = continuation frame of a multi-frame response // 128 = FIN frame os a multi-frame response // signalR send data in JSON format, and it send empty messages (empty json document) on a regular basis if( (n != 2) && flags !=1 ) // filter out empty jsons and multiframe responses (multiframe will be treated further on) { cout << "RCV[" << msg_cnt << "]=> " << buffer << " ===== " << unsigned(flags) << endl; } if(flags == 1){ // if I get a start frame of a multi-frame response means that I am getting something usefull from signalR string str(buffer); out += str; // due to flag == 1, we are expecting several frames, until we got flag == 128 do{ n = ws->receiveFrame(buffer, sizeof(buffer), flags); string str(buffer); out += str; // we add the next frame/frames to the out variable, to construct the whole JSON message str = ""; memset(buffer, 0, sizeof buffer); // be sure to empty the buffer to don't end up with junk }while(flags != 128); cout << endl << "=> " << out << endl; //not as we got a valid response from signalR endpoint, lets process it //convert the out variable and pass is as a Document to the JSON parser const char * c = out.c_str(); rapidjson::Document document; document.Parse<0>(c); out = document["M"][rapidjson::SizeType(0)]["A"][rapidjson::SizeType(1)].GetString(); // get out only the actual sent message from the response message SendMessageToMain(out.c_str()); cout << "Msg Received"; message_action(api_endpoint_url,out); // do something with the message in the message_action function out = ""; } msg_cnt++; memset(buffer, 0, sizeof buffer); // we always cleanup } ws->shutdown(); } // if something goes wrong with the connection, we try to recover catch (WebSocketException& exc0) { cout <<"WebSocketException "<< exc0.displayText() << endl; } catch (Poco::TimeoutException& exc1) // handle webclient errors { goto conn; // lets try again from the top cout <<"TimeoutException "<< exc1.displayText() << endl; // return 1; } catch (ConnectionResetException& exc) // handle connec errors { goto conn; // lets try again from the top cout << "!!!ConnectionResetException:" << exc.displayText() << endl; // return 1; } cout << strerror(errno) << endl; return 0; }