Ruby 从TCPSocket发送到EventMachine的消息被截断为16k
我有一个客户端ruby进程,它试图将数据发送到构建在EventMachine上的服务。工作流程很简单。客户机总是发起一个请求,并且总是期望得到响应 当从TCPSocket发送数据时,它显然将数据截断到大约16k。关于我做错了什么或者我做了哪些假设需要重新思考,有什么建议吗?大概我在EM中做了一些错误的事情,我需要积累所有发送的数据,但我不知道如何做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
# 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}上接收到数据
@缓冲区