Я новичок в программировании Win32 API, и я пытаюсь написать клиент xmpp для платформы Windows, используя Win32 API и библиотеки Gloox xmpp. У gloox есть собственный цикл обработки событий, в то время как в Windows GUI также есть цикл обработки сообщений. Мне не очень понятно, как использовать эти две петли вместе.
Из глокс-документа:
Блокирующие и неблокирующие соединения
Для каких-то ботов идеально подходит блокирующее соединение (поведение по умолчанию). Все, что делает бот - это реагирует на события, поступающие с сервера. Однако для клиентов конечного пользователя или чего-либо еще с графическим интерфейсом это далеко не идеально.
В этих случаях могут использоваться неблокирующие соединения. Если вызывается ClientBase :: connect (false), функция возвращается сразу после установления соединения. В этом случае программист обязан инициировать получение данных из сокета.
Самый простой способ - периодически вызывать ClientBase :: recv () с требуемым временем ожидания (в микросекундах) в качестве параметра. Значение по умолчанию -1 означает блокировку вызовов до тех пор, пока не будут получены какие-либо данные, которые затем автоматически анализируются.
Цикл сообщений в окне:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
Окно proc:
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
TCHAR str[100];
StringCbPrintf(str, _countof(str), TEXT("Message ID:%-6x:%s"), msg, GetStringMessage(msg));
OutputDebugString(str);
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (msg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hdc, TEXT("DRAW TEXT ON CLIENT AREA"), -1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
блокирующее соединение gloox
JID jid( "jid@server/resource" );
Client* client = new Client( jid, "password" );
client->registerConnectionListener( this );
client->registerPresenceHandler( this );
client->connect();// here will enter event loop
глокс неблокирующее соединение
Client* client = new Client( ... );
ConnectionTCPClient* conn = new ConnectionTCPClient( client, client->logInstance(), server, port );
client->setConnectionImpl( conn );
client->connect( false );
int sock = conn->socket();
[...]
Мне не очень понятно, как я могу
периодически вызывать ClientBase :: recv () с желаемым таймаутом (в микросекундах) в качестве параметра
с таймером? или многопоточное программирование? или есть лучшее решение?
Любые предложения приветствуются
Спасибо