3

I am working on boost websockets for asynchronous communication between the client and server.

Now I am printing the time elapsed during the program with boost::timer::auto_cpu_timer. It is displaying the time elapsed in seconds.

My program snippet is given below:

This function sends the data to the websocket:

void WebSocketSession::WriteSocket(beast::error_code ec) {
    if (ec)
         return fail(ec, "ssl_handshake");
    cout << "Authorised" <<endl;
    
    //Start the timer
    BoostTimer.start();
    
    // Send the Data message
    ws_.async_write(net::buffer(DATAMSG),
            bind(&WebSocketSession::ReadSocket, shared_from_this(), placeholders::_1,placeholders::_2));
}

This function reads the websocket response

void WebSocketSession::ReadSocket(beast::error_code ec, size_t bytes_transferred) {
    boost::ignore_unused(bytes_transferred);
    if (ec)
         return fail(ec, "WriteSocket Failed");

    cout << "Time Elapsed before reading WS : " << TimeElapsed() << endl;

    try {
        ws_.read(ReadBuffer_);
    } catch (exception *e) {
        cerr << "Error: " << e->what() << endl;
    }

    cout << "Time Elapsed after reading WS : " << TimeElapsed() << endl;
    
    // Display the buffer into stringstream
    cout << beast::buffers(ReadBuffer_.data());
    
    // Clear the websocket buffer
    ReadBuffer_.consume(ReadBuffer_.size());

    cout << "Time Elapsed before moving ahead : " << TimeElapsed() << endl;

    // Decision tree

    // IsGstFileWriteDone() gives "true" when the file is written... that file is not related to this context. An event is pushed saying FILE_WRITE_DONE
        if (mIbmWatsonobj->IsGstFileWriteDone()){
            cout<< "Going to CloseSocket" << endl;
            WebSocketSession::CloseSocket(ec, 0);
        }else{
            cout<< "Going to ReadSocket" << endl;
            WebSocketSession::ReadSocket(ec, 0);
        }
}

This function closes the web socket

void WebSocketSession::CloseSocket(beast::error_code ec, size_t bytes_transferred) {
    boost::ignore_unused(bytes_transferred);
    if (ec)
        return fail(ec, "ReadSocket Failed");

    cout << "CLOSING" <<endl;
    
    // Close the WebSocket connection
    ws_.close(websocket::close_code::normal);
}

Here is how my program output looks like: The response received from websocket is shown in grey (output of cout << beast::buffers(ReadBuffer_.data());) rest are couts printed at various places in program. The time elapsed is in seconds

IBM Authorised
Time Elapsed before reading WS : 0
Time Elapsed after reading WS : 0.3

{  
    "state": "listening"  
}

Time Elapsed before moving ahead : 0.3
Going to ReadSocket
Time Elapsed before reading WS : 0.3
Time Elapsed after reading WS : 2.1

{
   "results": [
      {
         "alternatives": [
            {
               "confidence": 0.89, 
               "transcript": "several tornadoes touch down as a line of severe some "
            }
         ], 
         "final": true
      }
   ], 
   "result_index": 0
}

Time Elapsed before moving ahead : 2.1
Going to ReadSocket
Time Elapsed before reading WS : 2.1
Time Elapsed after reading WS : 2.1

{
   "state": "listening"
}

Time Elapsed before moving ahead : 2.1
Going to ReadSocket
Time Elapsed before reading WS : 2.1

Event pushed : FILE_WRITE_DONE

Time Elapsed after reading WS : 34

{
   "error": "Session timed out."
}

Time Elapsed before moving ahead : 34

//PROGRAM EXITS WITH -1

Question:

After 2.1 seconds the program goes to ReadSocket again where the ws_.read(ReadBuffer_); is blocking the execution for almost 32secs untill it receives something from socket, in this case it receives the "session timeout".

How can I move to the CloseSocket while this block is on for say 5 sec. That is if at any point of time I have ws_.read blocking my code for more than 5 sec I want to put my behaviour, say CloseSocket.

Community
  • 1
  • 1
RC0993
  • 898
  • 1
  • 13
  • 44
  • 1
    https://stackoverflow.com/questions/47378022/how-to-simulate-boostasiowrite-with-a-timeout/47381372#47381372 – sehe Apr 12 '19 at 10:55

1 Answers1

0

Or you can just use the new Boost.Beast in 1.70.0 which supports built-in timeouts on websocket operations: https://www.boost.org/doc/libs/1_70_0/libs/beast/doc/html/beast/using_websocket/timeouts.html

Vinnie Falco
  • 5,173
  • 28
  • 43
  • Hi @VinnieFalco Yes that works with the 1.70.0 and 1.68.0 as well ([link](https://stackoverflow.com/q/55708200/10862144)) – RC0993 Apr 19 '19 at 04:24