0

個人的な HTML + Javascript チャットに使用する websocketpp ライブラリを使用して、単純なブロードキャスト サーバーをセットアップしました。1つだけ例外を除いて、今まではすべてが完璧でした。このチャットは、同時に 2 人だけを対象としています。3 分の 1 が入ろうとすると、ドアを閉めなければなりません。したがって、ロジックは次のとおりです。

1 -> サーバーがリッスンしています。

2 -> アリスが接続します。

3 -> ボブが接続します。

4 -> サーバーがリッスンを停止します。Alice + Bob にブロードキャストします。

5 -> Carlos は接続を試みますが、ポートが閉じられます。

6 -> ボブが切断します。

7 -> カルロスが接続します。

8 -> サーバーがリッスンを停止します。Alice + Carlos にブロードキャストします。

最初はこれは簡単なことだと思っていましたが、多くのエラーと読書の後、私は単に立ち往生しています。ハンドシェーク プロセス後にサーバーのリッスンを停止することはできますが、その後、message_handlerサーバー側での動作が停止し、クライアントが完全に接続されているにもかかわらず、クライアントからメッセージを取得できません。私は について知ってset_validate_handlerおり、同時に 2 つの接続のみを許可するように既に設定していますが、これによりサーバーはリッスンしたままになります。私が必要としているのは、サーバーがポートでのリッスンを停止する方法です。

私はリスニングを閉じて、この方法ですでに確立された接続を維持しようとしています:

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 )

4

1 に答える 1

0

チャット アプリのデザインを再考することをお勧めしますが (アプリ全体で 2 つの接続を行うよりも、それぞれ 2 人の参加者がいるチャットルームを用意したほうがよいのではないでしょうか?)、簡単な「汚い」ソリューションを作成できると思います...

...「グローバル」カウンターを用意して、数が多すぎる場合は単に接続を拒否しないのはなぜですか?

あなたのコードから借用すると、おそらく次のようになります (これが機能するかどうかはわかりません。これは単なる概要です)。

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 フレームワークを使用して 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

マルチスレッド セキュリティを追加しましたが、アプリがシングル スレッドの場合はおそらく必要ありません。

これは醜いですが、うまくいくはずです。

幸運を!

于 2015-07-12T21:41:29.957 に答える