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";
}