4

EventMachine プロトコルとして実装したカスタム Protobuf ベースのプロトコルがあり、サーバーとクライアント間の安全な接続を介して使用したいと考えています。クライアントからサーバーにメッセージを送信するたびに、送信される Protobuf のシリアル化された文字列のサイズを表す 4 バイトの整数をメッセージの先頭に追加して、サーバーがネットワークを解析する前にネットワークから読み取るバイト数を認識できるようにします。データを Protobuf メッセージに戻します。

クライアントとサーバーの両方のプロトコル ハンドラーでコールバック メソッドを呼び出しstart_tlsていpost_initます。サーバー ハンドラーのメソッドには、サーバーの秘密鍵と証明書が渡されます。私が出力しているログメッセージに基づいて、この段階でエラーが発生していないようです。

問題が発生するreceive_dataのは、サーバーのハンドラー コードのコールバックでデータの解析を開始するときです... 4 バイトのデータをネットワークから読み取り、それを整数にアンパックしますが、アンパックされる整数は同じ整数ではありません。クライアントから送信します (つまり、17 を送信していますが、134222349 を受信して​​います)。

これは、TLS を使用しない場合には発生しないことに注意してください...start_tlsクライアント コードとサーバー コードの両方で呼び出しを削除すると、すべて正常に動作します。

receive_dataTLS が使用されている場合、SSL/TLS データがコールバックに渡されるのは事実ですか? その場合、クライアントからのデータがいつ開始されるかをどのように知ることができますか? このユースケースについて説明しているサンプルコードが見つからないようです...

4

1 に答える 1

8

OK、それで、EventMachine Google Groupへのクロスポストを介して、私は自分の問題がここにあるのかを理解しました。ssl_handshake_completed基本的に、コールバックが呼び出されるまで待機していなかったため、TLSハンドシェイクが実行される前に、クライアントからサーバーにデータを送信しようとしていました。

将来誰かがこの投稿に出くわした場合に備えて、これが私が機能するようになったコードです。:)

サーバー側のハンドラーコード:

require 'eventmachine'

class ServerHandler < EM::Connection
  def post_init
    start_tls :private_key_file => 'server.key', :cert_chain_file => 'server.crt', :verify_peer => false
  end

  def receive_data(data)
    puts "Received data in server: #{data}"
    send_data(data)
  end
end

クライアント側のハンドラーコード:

require 'eventmachine'

class ClientHandler < EM::Connection
  def connection_completed
    start_tls
  end

  def receive_data(data)
    puts "Received data in client: #{data}"
  end

  def ssl_handshake_completed
    send_data('Hello World! - 12345')
  end
end

サーバーを起動するコード:

EventMachine.run do
  puts 'Starting server...'
  EventMachine.start_server('127.0.0.1', 45123, ServerHandler)
end

クライアントを起動するコード:

EventMachine.run do                      
  puts 'Starting client...'              
  EventMachine.connect('127.0.0.1', 45123, ClientHandler)
end
于 2012-12-16T20:11:17.373 に答える