2014-10-16 191 views
2

我正在使用Poco C++庫來設置websocket服務器,客戶端可以連接並將一些數據傳輸到其web界面。所以我有一個連續發送數據的循環,我也希望通過使用receiveFrame()函數來監聽客戶端是否關閉連接,其餘的客戶端完全是被動的,並且不發送任何數據或任何數據。問題是receiveFrame()阻塞了連接,這不是我想要的。我基本上想檢查客戶端是否還沒有調用close()javascript函數,並且如果它有停止流數據。我試過使用Poco C++ websockets - 如何以非阻塞的方式使用?

ws.setBlocking(false); 

但是現在receiveFrame在每次調用時都會引發異常。我也嘗試完全移除receiveFrame,如果通過關閉瀏覽器終止連接,但是如果客戶端調用close()函數,服務器仍嘗試向客戶端發送數據,則該方法起作用。那我該如何解決這個問題呢?有沒有辦法來檢查是否有客戶端框架被接收,如果不是隻是繼續?

回答

3

你可以在一個單獨的線程中重複調用Socket :: select()(有超時)當你檢測到一個可讀的套接字時,調用receiveFrame()。儘管名稱具有誤導性,但Socket :: select()調用在可用平臺上包裝epoll()或poll()。

你也可以通過Poco::NotificationQueue s稍微複雜一些,但也許更優雅的方式來實現它,每當插座可讀並且讀取處理程序中的數據時發佈通知。

+0

Select()確實實現我想實現的目標,謝謝! – SilverTear 2014-10-17 11:05:04

0

setBlocking()沒有達到您所期望的效果。這裏有一點就可以了信息: 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會拋出一個timeoutexception並關閉連接,這並不好。 – SilverTear 2014-10-16 18:28:36

+0

嗯,我不確定這是否適用於WebSockets,但使用普通套接字,我使用Poco的SocketReactor類並定義一個處理程序。當連接關閉時,它會觸發類的終止,我可以將所有清理工作都放到解構器中。由於SocketReactor會自動產生一個新的線程,所有其他的東西都可以按需運行,而不會被套接字阻塞。最壞的情況下,你可以自己產生一個線程,只需使用receiveFrame() – 2014-10-16 19:10:58