2014-10-16 3 views
2

Я использую библиотеки Poco C++ для установки сервера websocket, с помощью которого клиенты могут подключаться и передавать некоторые данные на свой веб-интерфейс. Поэтому у меня есть цикл, который непрерывно отправляет данные, и я также хочу слушать, закрывает ли клиент соединение с помощью функции receiveFrame(), а для остальных клиент полностью пассивен и не отправляет никаких данных или вообще ничего. Проблема в том, что receiveFrame() блокирует соединение, чего я не хочу. Я в основном хочу проверить, не вызвал ли клиент еще функцию javascript close() и прекратил передачу данных, если это имеет место. Я попытался использоватьPoco C++ websockets - как использовать неблокирующий способ?

ws.setBlocking(false); 

Но теперь receiveFrame вызывает исключение каждый раз, когда он вызывается. Я также попытался полностью удалить getFrame, который работает, если соединение завершено закрытием браузера, но если клиент вызывает функцию close(), сервер по-прежнему пытается отправить данные клиенту. Так как я могу снять это? Есть ли способ проверить, есть ли клиентские фреймы, и если не продолжать?

ответ

3

Вы можете неоднократно вызывать Socket :: select() (с таймаутом) в отдельном потоке; когда вы обнаруживаете читаемый сокет, вызовите функцию receiveFrame(). Несмотря на вводящее в заблуждение имя, вызов Socket :: select() обертывает epoll() или poll() на платформах, где они доступны.

Вы также можете реализовать это в несколько более сложном, но, возможно, более элегантном стиле с Poco::NotificationQueue, отправляя уведомление каждый раз, когда сокет читается и считывает данные в обработчике.

+0

Select() действительно то, чего я хочу достичь, спасибо! – SilverTear

0

комплектBlocking() не делает, что вы ожидаете от этого. Вот немного информации о нем: http://www.scottklement.com/rpg/socktut/nonblocking.html

То, что вы, вероятно, хотите сделать, это использовать setReceiveTimeout() на вашу розетку, чтобы контролировать, как долго он будет ждать, прежде чем дать вам вернуть контроль. Затем проверьте свой ответ и зациклируйте все, если необходимо. В документах Poco больше информации о том, как использовать эту часть API. Просто найдите WebSockets.

+0

Когда я использую ws.setReceiveTimeout (Poco :: Timespan (0, 500)); для установки тайм-аута до 500 микросекунд, он все еще блокируется. Когда я устанавливаю ws.setReceiveTimeout (Poco :: Timespan (1, 0)); receiveFrame выдает исключение timeout и закрывает соединение, что плохо. – SilverTear

+0

Хм, я не уверен, что это будет работать для WebSockets, но с обычными сокетами я использую класс SocketReactor Poco и определяю обработчик. Когда соединение закрывается, оно вызывает завершение класса, где я могу просто поместить всю мою очистку в деконструктор. Поскольку SocketReactor автоматически генерирует новый поток, все остальное может запускаться так, как требуется, без блокировки при получении сокетов. В худшем случае вы можете сами создать поток и просто заблокировать этот поток с помощью receiveFrame() –

Смежные вопросы