WinHttp websockets listener

280 views Asked by At

I am trying to develop a WebSockets client in C++ using WinHttp. I am making very slow progress (I am .NET developer). I have my WS server developed in .NET 6 and now I am working on a C++ console app that connects to the server and listens for messages.

So far I successfully connect to the server and upgrade the connection to WS but struggle setting up the callback that triggers when a new message was sent from the server. I spent hours finding an example with no success.

Can someone please help me how to set the callback for the below code or provide me with a working example?

static void CALLBACK Callback(HINTERNET handle,
    DWORD_PTR context,
    DWORD code,
    void* info,
    DWORD length)
{
    switch (code) {

        case WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE:
        {
            int i = 0;
            break;
        }

        case WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED:
        {
            int i = 0;
            break;
        }

        case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE:
        {
            int i = 0;
            break;
        }
        
    default:
        {
        }
    }


    if (0 != context)
    {

    }
}



int main()
{

    DWORD dwError = ERROR_SUCCESS;
    BOOL fStatus = FALSE;
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL  bResults = FALSE;
    HINTERNET  hSession = NULL, hConnect = NULL, hRequest = NULL, hWebSocket = NULL;

    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen(L"WinHTTP Example/1.0",
        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS,
        0);
    //WINHTTP_FLAG_ASYNC);

    if (hSession == NULL)
    {
        dwError = GetLastError();
    }

    // Setup the status callback function.
    WINHTTP_STATUS_CALLBACK isCallback = WinHttpSetStatusCallback(hSession,
        (WINHTTP_STATUS_CALLBACK)Callback,
        WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS,
        NULL);


    hConnect = WinHttpConnect(hSession, L"localhost", 5004, 0);

    if (hConnect == NULL)
    {
        dwError = GetLastError();
    }


    // Create an HTTP request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest(hConnect,
            L"GET",
            L"/ws",
            NULL,
            WINHTTP_NO_REFERER,
            WINHTTP_DEFAULT_ACCEPT_TYPES,
            0);//WINHTTP_FLAG_SECURE); // flags

    if (hRequest == NULL)
    {
        dwError = GetLastError();
    }


    //
    // Request protocol upgrade from http to websocket.
    //
#pragma prefast(suppress:6387, "WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET does not take any arguments.")
    fStatus = WinHttpSetOption(hRequest,
        WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET,
        NULL,
        0);

    if (!fStatus)
    {
        dwError = GetLastError();
    }



    // Send a request.
    if (hRequest)
        fStatus = WinHttpSendRequest(hRequest,
            WINHTTP_NO_ADDITIONAL_HEADERS,
            0,
            WINHTTP_NO_REQUEST_DATA,
            0,  // request data length
            0,  // total length
            0); // context

    if (!fStatus)
    {
        dwError = GetLastError();
    }

    fStatus = WinHttpReceiveResponse(hRequest, 0);

    if (!fStatus)
    {
        dwError = GetLastError();
    }


    //
    // Application should check what is the HTTP status code returned by the server and behave accordingly.
    // WinHttpWebSocketCompleteUpgrade will fail if the HTTP status code is different than 101.
    //
    hWebSocket = WinHttpWebSocketCompleteUpgrade(hRequest, NULL);

    if (hWebSocket == NULL)
    {
        dwError = GetLastError();
    }


    //
    // The request handle is not needed anymore. From now on we will use the websocket handle.
    //
    WinHttpCloseHandle(hRequest);
    hRequest = NULL;

    std::cout << "Connected to WS!\n";

}
0

There are 0 answers