2012-11-19 33 views
4

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

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

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

需要注意的是,当我不使用TLS这不会发生......一切,如果我删除在客户端和服务器代码同时start_tls电话工作正常。

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

回答

8

好的,所以通过cross-post到EventMachine Google Group,我想出了我的问题在这里。本质上,我试图在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