title: In-memory stream for Ruby
body: <p>When working with Protocol Buffers the real message size becomes known when a whole object is written to <code>IO</code>. So I use following approach: write object to intermediate stream, get it's size and then write whole data, with header containing size int, to TCP socket.</p>
  
  <p>What I do not like in following code is the <code>message_size</code> function which uses real disk file instead of memory stream.</p>
  
  <pre><code>require 'protocol_buffers'
  
  module MyServer
    class AuthRequest &lt; ProtocolBuffers::Message
      required :int32, :vers, 1
      required :int32, :orgID, 2
      required :string, :password, 3
    end
  
    class MyServer
      def self.authenticate(socket, params)
        auth = AuthRequest.new(:vers =&gt; params[:vers], :orgID =&gt; params[:orgID], :password =&gt; params[:password])
        size = message_size(auth)
        if size.present?
          socket.write([size, 0].pack 'NN')
          auth.serialize(socket)
          socket.flush
        end
      end
  
      def self.message_size(obj)
        size = nil
        io = File.new('tempfile', 'w')
        begin
          obj.serialize(io)
          io.flush
          size = io.stat.size + 4
        ensure
          io.close
        end
        size
      end
    end
  end
  </code></pre>
  
  <p>Controller:</p>
  
  <pre><code>require 'my_server'
  require 'socket'
  
  class MyServerTestController &lt; ActionController::Base
    def test
      socket = TCPSocket.new('192.168.1.15', '12345')
      begin
        MyServer::MyServer.authenticate(socket, {vers: 1, orgID: 100, password: 'hello'})
      ensure
        socket.close
      end
    end
  end
  </code></pre>