当我尝试通过java连接到我的ruby sinatra服务器时,我收到错误NoMethodError: undefined method 'bytesize'
。
这是我的ruby代码,我怀疑我需要某种方法,它在客户端连接时运行,但我不确定:
require 'sinatra'
get '/hello' do
'this page displays hello'
end
get '/' do
'this page is the main page'
end
这是我的java应用程序的代码:
private static Socket connect;
private static OutputStream output;
private static InputStream input;
public static void main(String[] args) throws IOException {
System.out.println("Connecting...");
connect = new Socket(InetAddress.getByName("localhost"), 4567);
System.out.println("Connected to: " + connect.getInetAddress().getHostName());
output = new ObjectOutputStream(connect.getOutputStream());
output.flush();
//input = new ObjectInputStream(connect.getInputStream());
System.out.println("Streams ready");
}
答案 0 :(得分:0)
我猜这种情况正在发生,因为以下代码中theory
出现Rack
错误,并且在Ruby服务器的Java客户端调用中出现theory
错误:
# Return the bytesize of String; uses String#size under Ruby 1.8 and
# String#bytesize under 1.9.
if ''.respond_to?(:bytesize)
def bytesize(string)
string.bytesize
end
else
def bytesize(string)
string.size
end
end
module_function :bytesize
这是在Sinatra使用的文件<rack>lib/rack/utils.rb
中,在这里:
headers["Content-Length"] = body.inject(0) { |l, p| l + Rack::Utils.bytesize(p) }.to_s
在#finish方法的文件<sinatra>lib/sinatra/base.rb
中,在检查calculate_content_length?
...无论如何,在#bytesize方法中没有测试string
是否为Nil ...它只是在测试以查看Ruby引擎本身是否支持#bytesize。
换句话说,我猜你的身体是Nil
,或者是一种不兼容的Object,它没有#bytesize方法,因为Rack
没有测试,它只是假设数据进入该方法是好的,并将方法调用传递给该对象,完全基于底层引擎...不基于user_agent。这是Rack
的理论错误。
进一步排除故障,我猜想在Java代码中有一些特定于user_agent的东西,而不是你的Ruby代码。甚至不是真正的user_agent,因为您似乎没有实例化“浏览器”而只是打开套接字连接。我猜你需要在正式请求,RFC兼容协议等中通过HTTP命令实际调用服务器......所以你需要发送一个语法正确的标题和正文。
我已经看到这种事情发生在奇怪的客户端,例如不能发送正确标题的模糊爬虫,或者不发送正文和只有标题。我进一步猜测打开Socket连接是不够的。您需要将标头和正文发送到服务器。我终于猜到你可能会使用一个类似于curl
或wget
的Java库,而不仅仅是操作一个原始套接字。这将为您做适当的协议聊天,并且只是从Ruby / Sinatra端点返回您正在寻找的内容。我在这里看了一下,发现: