Ruby 从TCPSocket发送到EventMachine的消息被截断为16k

Ruby 从TCPSocket发送到EventMachine的消息被截断为16k,ruby,eventmachine,Ruby,Eventmachine,我有一个客户端ruby进程,它试图将数据发送到构建在EventMachine上的服务。工作流程很简单。客户机总是发起一个请求,并且总是期望得到响应 当从TCPSocket发送数据时,它显然将数据截断到大约16k。关于我做错了什么或者我做了哪些假设需要重新思考,有什么建议吗?大概我在EM中做了一些错误的事情,我需要积累所有发送的数据,但我不知道如何做 # client.rb def send_messages arr arr = Array(messages) if arr.length

我有一个客户端ruby进程,它试图将数据发送到构建在EventMachine上的服务。工作流程很简单。客户机总是发起一个请求,并且总是期望得到响应

当从TCPSocket发送数据时,它显然将数据截断到大约16k。关于我做错了什么或者我做了哪些假设需要重新思考,有什么建议吗?大概我在EM中做了一些错误的事情,我需要积累所有发送的数据,但我不知道如何做

# client.rb
def send_messages arr
  arr = Array(messages)
  if arr.length > 0
    logger.debug { "Sending #{ arr.length } messages" }


    marshaled = Marshal.dump(arr)
    logger.debug { "Marshaled data #{ marshaled.length } bytes" } # roughly 200k

    socket = TCPSocket.new(host, port)
    written = socket.write(marshaled)
    logger.debug { "Apparently sent #{ written } bytes" } # same size
    socket.close_write

    data = socket.read
    logger.debug { "Received #{ data.length } bytes from service" }
    Marshal.load(data)
  end

rescue Exception => ex
  logger.error "Client threw exception communicating with service :: #{ ex.message }"
  raise ex
ensure
  socket.close if socket
end
客户端上的日志记录如下所示:

D, [2017-01-12T10:02:56.908857 #9360] DEBUG -- : Sending 1 messages 
D, [2017-01-12T10:02:56.909907 #9360] DEBUG -- : Marshaled data length 205941 bytes
D, [2017-01-12T10:02:56.910373 #9360] DEBUG -- : Apparently sent 205941 bytes
D, [2017-01-12T10:02:56.955270 #9360] DEBUG -- : Received 0 bytes from service
D, [2017-01-12T10:02:56.910251 #9330] DEBUG -- : In evented server initialize...
D, [2017-01-12T10:02:56.910319 #9330] DEBUG -- : -- someone connected to the server
D, [2017-01-12T10:02:56.910419 #9330] DEBUG -- : -- received data at the server 16384
D, [2017-01-12T10:02:56.910463 #9330] DEBUG -- : -- about to deserialize 16384 bytes
E, [2017-01-12T10:02:56.912067 #9330] ERROR -- : ** Error in processing request of 16384 bytes
在服务器端

class EventedServer < EM::Connection

  attr_reader :context

  def initialize context
    raise "Context must be defined" unless context
    @context = context
  end

  def post_init
    logger.debug { "-- someone connected to the server" }
  end

  def connection_completed
    logger.debug { "-- connection completed" }
  end

  def unbind
    logger.debug { "-- unbind" }
  end

  def receive_data data
    logger.debug { "-- received data at the server #{ data.length }" } # approx 16k
    send_data(process(data))
  end

  def process request

    logger.debug { "-- about to deserialize #{ request.length } bytes" }
    model = Marshal.load(request)
    logger.debug { "-- received #{ model.class.name }" }

    context.process_message(model)

    # Send data the application needs to stay up to date.
    response = context.application(app_name).pending_configurations
    logger.debug { "-- about to send #{ response.keys } for #{ app_name }" }
    Marshal.dump(response)
  rescue Exception => e
    logger.error("** Error in processing request of #{ request.length } bytes")
    raise e
  end
end

简单的回答是,
receive_data
不像我想象的那样等待返回所有数据。需要缓冲区。在我的例子中,任何大于16k的消息都需要缓冲。我当前的代码如下所示:

  def post_init
    logger.debug { "-- someone connected to the server" }
    @buffer = []
    logger.debug { "-- initializing message buffer" }
  end

  DELIMITER = "\nDELIM\n"

  def receive_data data

    # NOTE: actual code checks to ensure data was not split in the delimiter
    if data.ends_with?(DELIMITER)
      logger.debug { "-- received data at the server #{ data.length }" }
      @buffer << data[0...(-1*DELIMITER.length)]
      joined_data = @buffer.join
      @buffer = []

      logger.debug { "-- total data received #{ joined_data.length }" }
      send_data(process(joined_data))
    else
      logger.debug { "-- received partial data at the server #{ data.length }" }
      @buffer << data
    end
  end
def post_init
logger.debug{--有人连接到服务器“}
@缓冲区=[]
logger.debug{--正在初始化消息缓冲区“}
结束
分隔符=“\n分隔符\n”
def接收数据
#注意:实际代码检查以确保数据未在分隔符中拆分
if data.u以?(分隔符)结尾
logger.debug{--在服务器#{data.length}上接收到数据
@缓冲区