2015-07-12 94 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!