C++ WebSocket Bidirectional Reading/Writing in Threads

Demonstrates how to simultaneously read and write a websocket connection in C++ with threads.


// Read task
static void read_task(CkWebSocket *pWsReader) {

    int i;
    for (i=1; i<=10; i++)
	{
	unsigned long startTick = GetTickCount();
	bool receivedFinalFrame = false;
	int count = 0;
	while (!receivedFinalFrame) 
	    {
	    if (!pWsReader->ReadFrame()) 
			{
			std::cout << pWsReader->lastErrorText() << std::endl;
			std::cout << "Read task failed." << std::endl;
			return;
			}
	    receivedFinalFrame = pWsReader->get_FinalFrame();
	    count++;
	    }
	std::cout << "Received: " << pWsReader->getFrameData() << std::endl;
	}

    std::cout << "Read task is exiting" << std::endl;
}

// Write task
static void write_task(CkWebSocket *pWsWriter) {

    char msg[2];
    msg[0] = 'A';
    msg[1] = '\0';
    int i;
    for (i=1; i<=10; i++)
	{
	if (!pWsWriter->SendFrame(msg,true)) 
		{
		std::cout << pWsWriter->lastErrorText() << std::endl;
		std::cout << "Write task failed." << std::endl;
		return;
	    }
	msg[0]++;
	}

    std::cout << "Write task is exiting" << std::endl;
}


bool WebSocketTesting::qa_websocket_chilkat_io_bidirectional(void)
    {
    const char *testName = "qa_websocket_chilkat_io_bidirectional";

    CkWebSocket wsReader;
    CkWebSocket wsWriter;
    CkRest rest;

    bool success = rest.Connect("websockets.chilkat.io",80,false,false);
    if (!success) return failed(testName,rest);

    if (!wsReader.UseConnection(rest)) return failed(testName,wsReader);

    if (!wsReader.AddClientHeaders())  return failed(testName,wsReader);

    if (!rest.fullRequestNoBody("GET","/wsChilkatEcho.ashx")) return failed(testName,wsReader);

    if (!wsReader.ValidateServerHandshake()) return failed(testName,wsReader);

    // The caller (wsWriter) will share the wsReader's already-established websocket connection.  
    // This allows for multi-threaded applications to simultaneously read and write a websocket.
    wsWriter.ShareConnection(wsReader);

    // Create two threads
    std::thread t1(read_task,&wsReader);
    std::thread t2(write_task,&wsWriter);

    // Wait for both threads to finish
    t1.join();
    t2.join();

    if (!wsWriter.SendClose(true,1000,"Closing this websocket.")) return failed(testName,wsWriter);
    if (!wsReader.ReadFrame()) return failed(testName,wsReader);

    return succeeded(testName);
    }