EventMachine中的TLS连接如何工作?

时间:2012-11-19 23:09:56

标签: ssl eventmachine

我有一个基于Protobuf的自定义协议,我已将其作为EventMachine协议实现,我想通过服务器和客户端之间的安全连接使用它。每次我从客户端向服务器发送消息时,我都会在消息前面加上一个4字节的整数,表示要发送的Protobuf序列化字符串的大小,以便服务器在解析之前知道要读取多少字节数。数据回到Protobuf消息。

我在客户端和服务器协议处理程序中的start_tls回调方法中调用post_init,服务器处理程序中的一个传递服务器的私钥和证书。根据我正在打印的日志消息,此阶段似乎没有发生错误。

我遇到麻烦的是当我开始在服务器的处理程序代码中的receive_data回调中解析数据时......我从线上读取4个字节的数据并将其解压缩为整数,但是整数获取解压缩不是我从客户端发送的相同整数(即我发送17,但接收134222349)。

请注意,当我不使用TLS时不会发生这种情况......如果我删除客户端和服务器代码中的start_tls调用,一切正常。

使用TLS时是否会将SSL / TLS数据传递给receive_data回调?如果是这样,我如何知道客户端的数据何时开始?我似乎无法找到任何讨论此用例的示例代码...

1 个答案:

答案 0 :(得分:8)

好的,通过cross-post到EventMachine Google群组,我发现了我的问题所在。本质上,我试图在完成TLS握手之前将数据从客户端发送到服务器,因为我没有等到调用ssl_handshake_completed回调。

这是我开始工作的代码,以防将来有人遇到这篇文章。 :)

服务器端的处理程序代码:

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