2014-10-16 2 views
2

Poco C++ 라이브러리를 사용하여 클라이언트가 웹 인터페이스에 연결하여 일부 데이터를 스트리밍 할 수있는 websocket 서버를 설정하고 있습니다. 따라서 데이터를 지속적으로 보내는 루프가 있고 클라이언트가 receiveFrame() 함수를 사용하여 연결을 닫으면 나머지는 클라이언트가 완전히 수동적이며 모든 데이터를 전송하지 않습니다. 문제는 receiveFrame()이 내가 원하지 않는 연결을 차단한다는 것입니다. 기본적으로 클라이언트가 아직 close() 자바 스크립트 함수를 호출하지 않았는지 확인하고 스트리밍 데이터가 있으면 중지합니다. 사용해 보았습니다Poco C++ websockets - 비 차단 방식으로 사용하는 방법?

ws.setBlocking(false); 

하지만 이제는 receiveFrame이 호출 될 때마다 예외가 발생합니다. 클라이언트가 close() 함수를 호출하면 서버는 여전히 클라이언트에 데이터를 보내려고 시도하지만 브라우저를 닫음으로써 연결이 종료되면 작동하는 receiveFrame을 완전히 제거하려고했습니다. 어떻게 이것을 풀 수 있습니까? 수신 할 클라이언트 프레임이 있는지 여부를 확인하는 방법이 있습니까?

답변

3

별도의 스레드에서 Socket :: select() (시간 초과)를 반복적으로 호출 할 수 있습니다. 읽을 수있는 소켓을 발견하면 receiveFrame()을 호출하십시오. 오해의 소지가있는 이름에도 불구하고 Socket :: select() 호출은 epoll() 또는 poll()을 사용할 수있는 플랫폼에서 래핑합니다.

소켓을 읽을 수 있고 핸들러에서 데이터를 읽을 때마다 알림을 게시하여 좀 더 복잡하지만 좀 더 세련된 방식으로 구현할 수도 있습니다 (Poco::NotificationQueue).

+0

Select()는 실제로 달성하고 싶은 것입니다. 감사합니다! – SilverTear

0

setBlocking() 당신이 기대하는대로하지 않습니다. 여기에 약간의 정보는 다음과 같습니다 http://www.scottklement.com/rpg/socktut/nonblocking.html

은 당신이 아마하고 싶은 것은 컨트롤을 환원 전에 대기하는 시간을 제어 할 소켓에 setReceiveTimeout()를 사용합니다. 그런 다음 응답을 테스트하고 필요한 경우 모든 것을 반복하십시오. Poco 문서에는 API의 해당 부분을 사용하는 방법에 대한 자세한 정보가 있습니다. 웹 소켓을 찾으십시오.

+0

ws.setReceiveTimeout을 사용할 때 (Poco :: Timespan (0, 500)); 타임 아웃을 500 마이크로 초로 설정하면 여전히 차단됩니다. ws.setReceiveTimeout을 설정할 때 (Poco :: Timespan (1, 0)); receiveFrame은 timeoutexception을 던지고 연결을 닫습니다. – SilverTear

+0

흠, 이것이 WebSocket에서 작동하는지 확실하지 않지만 일반 소켓에서는 Poco의 SocketReactor 클래스를 사용하고 핸들러를 정의합니다. 연결이 닫히면 클래스의 종료가 트리거되어 deconstructor에 모든 정리 작업을 넣을 수 있습니다. SocketReactor는 자동으로 새 스레드를 생성하므로 소켓 수신에 의해 차단되지 않고 필요한만큼 실행될 수 있습니다. 최악의 시나리오 당신은 스레드를 직접 스폰하고 receiveFrame()을 사용하여 해당 스레드를 차단할 수 있습니다. –