在Ruby中发送HTTP / 2 POST请求

我正在尝试使用基于HTTP / 2的新Apple推送通知 API。

我找到了http-2 Ruby gem,但文档并不清楚如何作为客户端发出请求。

如何在Ruby / Rails中发出HTTP / 2请求?

有一个在此文件中创建HTTP / 2客户端的示例。 它可以适应这样的APN请求:

require 'socket' require 'http/2' payload = '{"foo":"bar"}' device_token = '00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0' # example sock = TCPSocket.new('api.development.push.apple.com', 443) conn = HTTP2::Client.new conn.on(:frame) do |bytes| puts "Sending bytes: #{bytes.unpack("H*").first}" sock.print bytes sock.flush end stream = conn.new_stream stream.on(:close) do sock.close end head = { ':scheme' => 'https', ':method' => 'POST', ':path' => "/3/device/#{device_token}", 'apns-id' => '123e4567-e89b-12d3-a456-42665544000', # or you could omit this header 'content-length' => payload.bytesize.to_s # should be less than or equal to 4096 bytes } puts 'Sending HTTP 2.0 request' stream.headers(head, end_stream: false) stream.data(payload) while !sock.closed? && !sock.eof? data = sock.read_nonblock(1024) puts "Received bytes: #{data.unpack("H*").first}" begin conn << data rescue => e puts "Exception: #{e}, #{e.message} - closing socket." sock.close end end 

免责声明:我是下面列出的两个gem的作者。

如果要发出HTTP / 2调用,可以考虑使用NetHttp2 ,它是Ruby的HTTP / 2客户端。

同步调用的用法示例:

 require 'net-http2' # create a client client = NetHttp2::Client.new("http://106.186.112.116") # send request response = client.call(:get, '/') # read the response response.ok? # => true response.status # => '200' response.headers # => {":status"=>"200"} response.body # => "A body" # close the connection client.close 

除了自己编写HTTP / 2调用之外,如果你想要一个使用新HTTP / 2细节的Apple推送通知gem并且可以嵌入到Rails环境中,那么你也可以考虑使用Apnotic 。

用法很简单:

 require 'apnotic' # create a persistent connection connection = Apnotic::Connection.new(cert_path: "apns_certificate.pem", cert_pass: "pass") # create a notification for a specific device token token = "6c267f26b173cd9595ae2f6702b1ab560371a60e7c8a9e27419bd0fa4a42e58f" notification = Apnotic::Notification.new(token) notification.alert = "Notification from Apnotic!" # send (this is a blocking call) response = connection.push(notification) # read the response response.ok? # => true response.status # => '200' response.headers # => {":status"=>"200", "apns-id"=>"6f2cd350-bfad-4af0-a8bc-0d501e9e1799"} response.body # => "" # close the connection connection.close 

我一直在为此实现客户端实现: https : //github.com/alloy/lowdown 。

到目前为止,我已经对它进行了广泛的测试,但直到下周它才会投入生产。 我喜欢它以获得更多测试,反馈等。

以下是使用async-http

 #!/usr/bin/env ruby require 'async' require 'async/logger' require 'async/http/client' require 'async/http/url_endpoint' Async.run do |task| endpoint = Async::HTTP::URLEndpoint.parse("https://www.google.com") client = Async::HTTP::Client.new(endpoint) headers = { 'accept' => 'text/html', } request = Async::HTTP::Request.new("www.google.com", "GET", "/search?q=cats", headers) response = client.call(request) body = response.read end 

这将根据需要协商HTTP / 1,HTTP / 2和SSL。