2015-07-12 96 views
0

我已經使用websocketpp庫設置了一個簡單的廣播服務器,用於個人HTML + Javascript聊天。一切都是完美的,直到現在,只有一個例外。此聊天僅供兩個人同時使用。如果有三分之一的人嘗試進來,他或她必須關上門。所以,邏輯是:只聽兩個連接websocketpp

1 - >服務器正在偵聽。

2 - > Alice連接。

3 - > Bob連接。

4 - >服務器停止收聽。廣播到Alice + Bob。

5 - >卡洛斯試圖連接,但得到一個端口關閉。

6 - > Bob斷開連接。

7 - >卡洛斯連接。

8 - >服務器停止收聽。廣播給Alice + Carlos。

起初我以爲這會是一件簡單的事情,但經過很多錯誤和閱讀後,我簡直就被卡住了。我可以讓服務器在握手過程後停止監聽,但在此之後,服務器端的message_handler停止工作,即使客戶端保持完美連接,客戶端也不會收到消息。我知道set_validate_handler,我已經設置爲只允許同時連接兩個連接,但是由於這一點,服務器仍在監聽。我需要的是一種使服務器停止監聽端口的方法。

我試圖關閉傾聽,並保持與已建立的連接是這樣的:

void on_open(connection_hdl hdl) 
{ 
    // Insert 
    m_connections.insert(hdl); 

    // Stop listening 
    m_server.stop_listening(); 
} 

但是,它給了我下面的輸出:

[2015-07-12 17:06:47] [connect] WebSocket Connection [::1]:58589 v13 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.132 Safari/537.36"/101 
[2015-07-12 17:06:47] [fail] WebSocket Connection Unknown - "" - 0 websocketpp:26 Operation canceled[2015-07-12 17:06:47] [info] Error getting remote endpoint: system:10009 (The file handle supplied is not valid) 
[2015-07-12 17:06:47] [info] asio async_shutdown error: system:10009 (The file handle supplied is not valid) 
remote_endpoint: The file handle supplied is not valid 

客戶端是無法連連接。否則,如果在建立連接後使用m_server.stop_listening();,則客戶端保持完美連接,但服務器停止接收其消息,或者至少我無法在void on_message(connection_hdl hdl, server::message_ptr msg)上獲得它們。

回答

0

儘管我會建議重新考慮聊天應用程序的設計(也許最好是讓每個聊天室有兩個參與者,而不是兩個連接的整個應用程序?),我認爲您可以編寫一個簡單的「髒」解決方案...

...爲什麼不有一個「全球」的計數器,只是拒絕連接,如果數量太高?

如果從你的代碼借,也許它會是這個樣子(我不知道這是否正常工作,這只是一個概要):

int connections_count = 0 
void on_open(connection_hdl hdl) 
{ 
    connections_count += 1 
    if(connections_count >= 2) { return connection_hdl.close} 
    // Insert 
    m_connections.insert(hdl); 
} 
void on_close (connection_hdl hdl) 
{ 
    connections_count -= 1 
} 

因爲我的C++編碼很爛,我會使用Plezi framework在Ruby中編寫一個快速服務器示例...把它看成是僞代碼,你可以在irb(Ruby的終端解釋器)運行:

require 'plezi' 

class ChatCtrl 
    def pre_connect 
     return self.class.add_client 
    end 

    def on_message data 
    broadcast :_post_data, data 
    end 

    def on_disconnect 
     self.class.remove_client 
    end 

    def _post_data data 
    response << data 
    end 

    # these are class methods, designated by adding `self.` to the name 
    # they hold the global number of connected clients. 
    # they also handle the multi-threading security, because Plezi is multi-threaded. 

    def self.add_client 
     @locker ||= Mutex.new # multi-thread security 
     @clients ||= 0 
     return false if @clients >= 2 
     @locker.synchronize { @clients += 1 } 
    end 
    def self.remove_client 
     @locker.synchronize { @clients -= 1 } 
    end 
end 

listen 

route '*', ChatCtrl 

exit 

我加了一些多線程安全的,但如果你的應用程序是單線程它可能不是必需的。

這是醜陋的,但它應該工作。

Goodluck!